/*
 *  Catch v2.2.3
 *  Generated: 2018-06-11 22:16:30.128800
 *  ----------------------------------------------------------
 *  This file has been merged from multiple headers. Please don't edit it directly
 *  Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved.
 *
 *  Distributed under the Boost Software License, Version 1.0. (See accompanying
 *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 */
#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
// start catch.hpp


#define CATCH_VERSION_MAJOR 2
#define CATCH_VERSION_MINOR 2
#define CATCH_VERSION_PATCH 3

#ifdef __clang__
#    pragma clang system_header
#elif defined __GNUC__
#    pragma GCC system_header
#endif

// start catch_suppress_warnings.h

#ifdef __clang__
#   ifdef __ICC // icpc defines the __clang__ macro
#       pragma warning(push)
#       pragma warning(disable: 161 1682)
#   else // __ICC
#       pragma clang diagnostic ignored "-Wunused-variable"
#       pragma clang diagnostic push
#       pragma clang diagnostic ignored "-Wpadded"
#       pragma clang diagnostic ignored "-Wswitch-enum"
#       pragma clang diagnostic ignored "-Wcovered-switch-default"
#    endif
#elif defined __GNUC__
#    pragma GCC diagnostic ignored "-Wparentheses"
#    pragma GCC diagnostic push
#    pragma GCC diagnostic ignored "-Wunused-variable"
#    pragma GCC diagnostic ignored "-Wpadded"
#endif
// end catch_suppress_warnings.h
#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
#  define CATCH_IMPL
#  define CATCH_CONFIG_ALL_PARTS
#endif

// In the impl file, we want to have access to all parts of the headers
// Can also be used to sanely support PCHs
#if defined(CATCH_CONFIG_ALL_PARTS)
#  define CATCH_CONFIG_EXTERNAL_INTERFACES
#  if defined(CATCH_CONFIG_DISABLE_MATCHERS)
#    undef CATCH_CONFIG_DISABLE_MATCHERS
#  endif
#  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
#endif

#if !defined(CATCH_CONFIG_IMPL_ONLY)
// start catch_platform.h

#ifdef __APPLE__
# include <TargetConditionals.h>
# if TARGET_OS_OSX == 1
#  define CATCH_PLATFORM_MAC
# elif TARGET_OS_IPHONE == 1
#  define CATCH_PLATFORM_IPHONE
# endif

#elif defined(linux) || defined(__linux) || defined(__linux__)
#  define CATCH_PLATFORM_LINUX

#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
#  define CATCH_PLATFORM_WINDOWS
#endif

// end catch_platform.h

#ifdef CATCH_IMPL
#  ifndef CLARA_CONFIG_MAIN
#    define CLARA_CONFIG_MAIN_NOT_DEFINED
#    define CLARA_CONFIG_MAIN
#  endif
#endif

// start catch_user_interfaces.h

namespace Catch
{
  unsigned int rngSeed();
}

// end catch_user_interfaces.h
// start catch_tag_alias_autoregistrar.h

// start catch_common.h

// start catch_compiler_capabilities.h

// Detect a number of compiler features - by compiler
// The following features are defined:
//
// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
// ****************
// Note to maintainers: if new toggles are added please document them
// in configuration.md, too
// ****************

// In general each macro has a _NO_<feature name> form
// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
// Many features, at point of detection, define an _INTERNAL_ macro, so they
// can be combined, en-mass, with the _NO_ forms later.

#ifdef __cplusplus

#  if __cplusplus >= 201402L
#    define CATCH_CPP14_OR_GREATER
#  endif

#  if __cplusplus >= 201703L
#    define CATCH_CPP17_OR_GREATER
#  endif

#endif

#if defined(CATCH_CPP17_OR_GREATER)
#  define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
#endif

#ifdef __clang__

#       define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  _Pragma( "clang diagnostic push" ) \
  _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
  _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
#       define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  _Pragma( "clang diagnostic pop" )

#       define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
  _Pragma( "clang diagnostic push" ) \
  _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
#       define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
  _Pragma( "clang diagnostic pop" )

#endif // __clang__

////////////////////////////////////////////////////////////////////////////////
// Assume that non-Windows platforms support posix signals by default
#if !defined(CATCH_PLATFORM_WINDOWS)
#define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
#endif

////////////////////////////////////////////////////////////////////////////////
// We know some environments not to support full POSIX signals
#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
#define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
#endif

#ifdef __OS400__
#       define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
#       define CATCH_CONFIG_COLOUR_NONE
#endif

////////////////////////////////////////////////////////////////////////////////
// Android somehow still does not support std::to_string
#if defined(__ANDROID__)
#    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
#endif

////////////////////////////////////////////////////////////////////////////////
// Not all Windows environments support SEH properly
#if defined(__MINGW32__)
#    define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
#endif

////////////////////////////////////////////////////////////////////////////////
// Cygwin
#ifdef __CYGWIN__

// Required for some versions of Cygwin to declare gettimeofday
// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
#   define _BSD_SOURCE

#endif // __CYGWIN__

////////////////////////////////////////////////////////////////////////////////
// Visual C++
#ifdef _MSC_VER

#  if _MSC_VER >= 1900 // Visual Studio 2015 or newer
#    define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
#  endif

// Universal Windows platform does not support SEH
// Or console colours (or console at all...)
#  if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
#    define CATCH_CONFIG_COLOUR_NONE
#  else
#    define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
#  endif

#endif // _MSC_VER

////////////////////////////////////////////////////////////////////////////////

// DJGPP
#ifdef __DJGPP__
#  define CATCH_INTERNAL_CONFIG_NO_WCHAR
#endif // __DJGPP__

////////////////////////////////////////////////////////////////////////////////

// Use of __COUNTER__ is suppressed during code analysis in
// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
// handled by it.
// Otherwise all supported compilers support COUNTER macro,
// but user still might want to turn it off
#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
#define CATCH_INTERNAL_CONFIG_COUNTER
#endif

#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
#   define CATCH_CONFIG_COUNTER
#endif
#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH)
#   define CATCH_CONFIG_WINDOWS_SEH
#endif
// This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
#   define CATCH_CONFIG_POSIX_SIGNALS
#endif
// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
#   define CATCH_CONFIG_WCHAR
#endif

#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
#    define CATCH_CONFIG_CPP11_TO_STRING
#endif

#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
#  define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
#endif

#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
#   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
#   define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
#endif
#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
#   define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
#   define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
#endif

// end catch_compiler_capabilities.h
#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
#ifdef CATCH_CONFIG_COUNTER
#  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
#else
#  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
#endif

#include <iosfwd>
#include <string>
#include <cstdint>

namespace Catch
{

  struct CaseSensitive
  {
    enum Choice
    {
      Yes,
      No
    };
  };

  class NonCopyable
  {
      NonCopyable( NonCopyable const &)              = delete;
      NonCopyable( NonCopyable &&)                  = delete;
      NonCopyable &operator = ( NonCopyable const &) = delete;
      NonCopyable &operator = ( NonCopyable && )     = delete;

    protected:
      NonCopyable();
      virtual ~NonCopyable();
  };

  struct SourceLineInfo
  {

    SourceLineInfo() = delete;
    SourceLineInfo( char const *_file, std::size_t _line ) noexcept
  :
    file( _file ),
          line( _line )
    {}

    SourceLineInfo( SourceLineInfo const &other )        = default;
    SourceLineInfo( SourceLineInfo &&)                  = default;
    SourceLineInfo &operator = ( SourceLineInfo const &) = default;
    SourceLineInfo &operator = ( SourceLineInfo && )     = default;

    bool empty() const noexcept;
    bool operator == ( SourceLineInfo const &other ) const noexcept;
    bool operator < ( SourceLineInfo const &other ) const noexcept;

    char const *file;
    std::size_t line;
  };

  std::ostream &operator << ( std::ostream &os, SourceLineInfo const &info );

  // Use this in variadic streaming macros to allow
  //    >> +StreamEndStop
  // as well as
  //    >> stuff +StreamEndStop
  struct StreamEndStop
  {
    std::string operator+() const;
  };
  template<typename T>
  T const &operator + ( T const &value, StreamEndStop )
  {
    return value;
  }
}

#define CATCH_INTERNAL_LINEINFO \
  ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )

// end catch_common.h
namespace Catch
{

  struct RegistrarForTagAliases
  {
    RegistrarForTagAliases( char const *alias, char const *tag, SourceLineInfo const &lineInfo );
  };

} // end namespace Catch

#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS

// end catch_tag_alias_autoregistrar.h
// start catch_test_registry.h

// start catch_interfaces_testcase.h

#include <vector>
#include <memory>

namespace Catch
{

  class TestSpec;

  struct ITestInvoker
  {
    virtual void invoke () const = 0;
    virtual ~ITestInvoker();
  };

  using ITestCasePtr = std::shared_ptr<ITestInvoker>;

  class TestCase;
  struct IConfig;

  struct ITestCaseRegistry
  {
    virtual ~ITestCaseRegistry();
    virtual std::vector<TestCase> const &getAllTests() const = 0;
    virtual std::vector<TestCase> const &getAllTestsSorted( IConfig const &config ) const = 0;
  };

  bool matchTest( TestCase const &testCase, TestSpec const &testSpec, IConfig const &config );
  std::vector<TestCase> filterTests( std::vector<TestCase> const &testCases, TestSpec const &testSpec, IConfig const &config );
  std::vector<TestCase> const &getAllTestCasesSorted( IConfig const &config );

}

// end catch_interfaces_testcase.h
// start catch_stringref.h

#include <cstddef>
#include <string>
#include <iosfwd>

namespace Catch
{

  class StringData;

  /// A non-owning string class (similar to the forthcoming std::string_view)
  /// Note that, because a StringRef may be a substring of another string,
  /// it may not be null terminated. c_str() must return a null terminated
  /// string, however, and so the StringRef will internally take ownership
  /// (taking a copy), if necessary. In theory this ownership is not externally
  /// visible - but it does mean (substring) StringRefs should not be shared between
  /// threads.
  class StringRef
  {
    public:
      using size_type = std::size_t;

    private:
      friend struct StringRefTestAccess;

      char const *m_start;
      size_type m_size;

      char *m_data = nullptr;

      void takeOwnership();

      static constexpr char const *const s_empty = "";

    public: // construction/ assignment
      StringRef() noexcept
    :
      StringRef( s_empty, 0 )
      {}

      StringRef( StringRef const &other ) noexcept
    :
      m_start( other.m_start ),
               m_size( other.m_size )
      {}

      StringRef( StringRef &&other ) noexcept
    :
      m_start( other.m_start ),
      m_size( other.m_size ),
      m_data( other.m_data )
      {
        other.m_data = nullptr;
      }

      StringRef( char const *rawChars ) noexcept;

      StringRef( char const *rawChars, size_type size ) noexcept
    :
      m_start( rawChars ),
               m_size( size )
      {}

      StringRef( std::string const &stdString ) noexcept
    :
      m_start( stdString.c_str() ),
      m_size( stdString.size() )
      {}

      ~StringRef() noexcept
      {
        delete[] m_data;
      }

      auto operator = ( StringRef const &other ) noexcept -> StringRef &
      {
        delete[] m_data;
        m_data = nullptr;
        m_start = other.m_start;
        m_size = other.m_size;
        return *this;
      }

      operator std::string() const;

      void swap( StringRef &other ) noexcept;

    public: // operators
      auto operator == ( StringRef const &other ) const noexcept -> bool;
      auto operator != ( StringRef const &other ) const noexcept -> bool;

      auto operator[] ( size_type index ) const noexcept -> char;

    public: // named queries
      auto empty() const noexcept -> bool
      {
        return m_size == 0;
      }
      auto size() const noexcept -> size_type
      {
        return m_size;
      }

      auto numberOfCharacters() const noexcept -> size_type;
      auto c_str() const -> char const *;

    public: // substrings and searches
      auto substr( size_type start, size_type size ) const noexcept -> StringRef;

      // Returns the current start pointer.
      // Note that the pointer can change when if the StringRef is a substring
      auto currentData() const noexcept -> char const *;

    private: // ownership queries - may not be consistent between calls
      auto isOwned() const noexcept -> bool;
      auto isSubstring() const noexcept -> bool;
  };

  auto operator + ( StringRef const &lhs, StringRef const &rhs ) -> std::string;
  auto operator + ( StringRef const &lhs, char const *rhs ) -> std::string;
  auto operator + ( char const *lhs, StringRef const &rhs ) -> std::string;

  auto operator += ( std::string &lhs, StringRef const &sr ) -> std::string &;
  auto operator << ( std::ostream &os, StringRef const &sr ) -> std::ostream &;

  inline auto operator "" _sr( char const *rawChars, std::size_t size ) noexcept -> StringRef
  {
    return StringRef( rawChars, size );
  }

} // namespace Catch

// end catch_stringref.h
namespace Catch
{

  template<typename C>
  class TestInvokerAsMethod : public ITestInvoker
  {
      void (C::*m_testAsMethod)();
    public:
    TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept :
      m_testAsMethod( testAsMethod ) {}

      void invoke() const override
      {
        C obj;
        (obj.*m_testAsMethod)();
      }
  };

  auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker *;

  template<typename C>
  auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker *
  {
    return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
  }

  struct NameAndTags
  {
    NameAndTags( StringRef const &name_ = StringRef(), StringRef const &tags_ = StringRef() ) noexcept;
    StringRef name;
    StringRef tags;
  };

  struct AutoReg : NonCopyable
  {
    AutoReg( ITestInvoker *invoker, SourceLineInfo const &lineInfo, StringRef const &classOrMethod, NameAndTags const &nameAndTags ) noexcept;
    ~AutoReg();
  };

} // end namespace Catch

#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF

#if defined(CATCH_CONFIG_DISABLE)
#define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
  static void TestName()
#define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
  namespace{                        \
    struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \
      void test();              \
    };                            \
  }                                 \
  void TestName::test()

#endif

///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
  static void TestName(); \
  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  static void TestName()
#define INTERNAL_CATCH_TESTCASE( ... ) \
  INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )

///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS

///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  namespace{ \
    struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \
      void test(); \
    }; \
    Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
  } \
  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  void TestName::test()
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
  INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )

///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS

// end catch_test_registry.h
// start catch_capture.hpp

// start catch_assertionhandler.h

// start catch_assertioninfo.h

// start catch_result_type.h

namespace Catch
{

  // ResultWas::OfType enum
  struct ResultWas
  {
    enum OfType
    {
      Unknown = -1,
      Ok = 0,
      Info = 1,
      Warning = 2,

      FailureBit = 0x10,

      ExpressionFailed = FailureBit | 1,
      ExplicitFailure = FailureBit | 2,

      Exception = 0x100 | FailureBit,

      ThrewException = Exception | 1,
      DidntThrowException = Exception | 2,

      FatalErrorCondition = 0x200 | FailureBit

    };
  };

  bool isOk( ResultWas::OfType resultType );
  bool isJustInfo( int flags );

  // ResultDisposition::Flags enum
  struct ResultDisposition
  {
    enum Flags
    {
      Normal = 0x01,

      ContinueOnFailure = 0x02,   // Failures fail test, but execution continues
      FalseTest = 0x04,           // Prefix expression with !
      SuppressFail = 0x08         // Failures are reported but do not fail the test
    };
  };

  ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );

  bool shouldContinueOnFailure( int flags );
  inline bool isFalseTest( int flags )
  {
    return ( flags & ResultDisposition::FalseTest ) != 0;
  }
  bool shouldSuppressFailure( int flags );

} // end namespace Catch

// end catch_result_type.h
namespace Catch
{

  struct AssertionInfo
  {
    StringRef macroName;
    SourceLineInfo lineInfo;
    StringRef capturedExpression;
    ResultDisposition::Flags resultDisposition;

    // We want to delete this constructor but a compiler bug in 4.8 means
    // the struct is then treated as non-aggregate
    //AssertionInfo() = delete;
  };

} // end namespace Catch

// end catch_assertioninfo.h
// start catch_decomposer.h

// start catch_tostring.h

#include <vector>
#include <cstddef>
#include <type_traits>
#include <string>
// start catch_stream.h

#include <iosfwd>
#include <cstddef>
#include <ostream>

namespace Catch
{

  std::ostream &cout();
  std::ostream &cerr();
  std::ostream &clog();

  class StringRef;

  struct IStream
  {
    virtual ~IStream();
    virtual std::ostream &stream() const = 0;
  };

  auto makeStream( StringRef const &filename ) -> IStream const *;

  class ReusableStringStream
  {
      std::size_t m_index;
      std::ostream *m_oss;
    public:
      ReusableStringStream();
      ~ReusableStringStream();

      auto str() const -> std::string;

      template<typename T>
      auto operator << ( T const &value ) -> ReusableStringStream &
      {
        *m_oss << value;
        return *this;
      }
      auto get() -> std::ostream & { return *m_oss; }

      static void cleanup();
  };
}

// end catch_stream.h

#ifdef __OBJC__
// start catch_objc_arc.hpp

#import <Foundation/Foundation.h>

#ifdef __has_feature
#define CATCH_ARC_ENABLED __has_feature(objc_arc)
#else
#define CATCH_ARC_ENABLED 0
#endif

void arcSafeRelease( NSObject *obj );
id performOptionalSelector( id obj, SEL sel );

#if !CATCH_ARC_ENABLED
inline void arcSafeRelease( NSObject *obj )
{
  [obj release];
}
inline id performOptionalSelector( id obj, SEL sel )
{
  if ( [obj respondsToSelector: sel] )
    return [obj performSelector: sel];
  return nil;
}
#define CATCH_UNSAFE_UNRETAINED
#define CATCH_ARC_STRONG
#else
inline void arcSafeRelease( NSObject *) {}
inline id performOptionalSelector( id obj, SEL sel )
{
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
#endif
  if ( [obj respondsToSelector: sel] )
    return [obj performSelector: sel];
#ifdef __clang__
#pragma clang diagnostic pop
#endif
  return nil;
}
#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
#define CATCH_ARC_STRONG __strong
#endif

// end catch_objc_arc.hpp
#endif

#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless
#endif

// We need a dummy global operator<< so we can bring it into Catch namespace later
struct Catch_global_namespace_dummy {};
std::ostream &operator<<(std::ostream &, Catch_global_namespace_dummy);

namespace Catch
{
  // Bring in operator<< from global namespace into Catch namespace
  using ::operator<<;

  namespace Detail
  {

    extern const std::string unprintableString;

    std::string rawMemoryToString( const void *object, std::size_t size );

    template<typename T>
    std::string rawMemoryToString( const T &object )
    {
      return rawMemoryToString( &object, sizeof(object) );
    }

    template<typename T>
    class IsStreamInsertable
    {
        template<typename SS, typename TT>
        static auto test(int)
        -> decltype(std::declval<SS &>() << std::declval<TT>(), std::true_type());

        template<typename, typename>
        static auto test(...)->std::false_type;

      public:
        static const bool value = decltype(test<std::ostream, const T &>(0))::value;
    };

    template<typename E>
    std::string convertUnknownEnumToString( E e );

    template<typename T>
    typename std::enable_if<
    !std::is_enum<T>::value  &&!std::is_base_of<std::exception, T>::value,
    std::string>::type convertUnstreamable( T const &)
    {
      return Detail::unprintableString;
    }
    template<typename T>
    typename std::enable_if<
    !std::is_enum<T>::value  &&std::is_base_of<std::exception, T>::value,
    std::string>::type convertUnstreamable(T const &ex)
    {
      return ex.what();
    }

    template<typename T>
    typename std::enable_if<
    std::is_enum<T>::value
    , std::string>::type convertUnstreamable( T const &value )
    {
      return convertUnknownEnumToString( value );
    }

#if defined(_MANAGED)
    //! Convert a CLR string to a utf8 std::string
    template<typename T>
    std::string clrReferenceToString( T ^ref )
    {
      if (ref == nullptr)
        return std::string("null");
      auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());
      cli::pin_ptr<System::Byte> p = &bytes[0];
      return std::string(reinterpret_cast<char const *>(p), bytes->Length);
    }
#endif

  } // namespace Detail

  // If we decide for C++14, change these to enable_if_ts
  template <typename T, typename = void>
  struct StringMaker
  {
    template <typename Fake = T>
    static
    typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
    convert(const Fake &value)
    {
      ReusableStringStream rss;
      // NB: call using the function-like syntax to avoid ambiguity with
      // user-defined templated operator<< under clang.
      rss.operator<<(value);
      return rss.str();
    }

    template <typename Fake = T>
    static
    typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
    convert( const Fake &value )
    {
#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)
      return Detail::convertUnstreamable(value);
#else
      return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
#endif
    }
  };

  namespace Detail
  {

    // This function dispatches all stringification requests inside of Catch.
    // Should be preferably called fully qualified, like ::Catch::Detail::stringify
    template <typename T>
    std::string stringify(const T &e)
    {
      return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);
    }

    template<typename E>
    std::string convertUnknownEnumToString( E e )
    {
      return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));
    }

#if defined(_MANAGED)
    template <typename T>
    std::string stringify( T ^e )
    {
      return ::Catch::StringMaker<T ^>::convert(e);
    }
#endif

  } // namespace Detail

  // Some predefined specializations

  template<>
  struct StringMaker<std::string>
  {
    static std::string convert(const std::string &str);
  };
#ifdef CATCH_CONFIG_WCHAR
  template<>
  struct StringMaker<std::wstring>
  {
    static std::string convert(const std::wstring &wstr);
  };
#endif

  template<>
  struct StringMaker<char const *>
  {
    static std::string convert(char const *str);
  };
  template<>
  struct StringMaker<char *>
  {
    static std::string convert(char *str);
  };

#ifdef CATCH_CONFIG_WCHAR
  template<>
  struct StringMaker<wchar_t const *>
  {
    static std::string convert(wchar_t const *str);
  };
  template<>
  struct StringMaker<wchar_t *>
  {
    static std::string convert(wchar_t *str);
  };
#endif

  // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,
  //      while keeping string semantics?
  template<int SZ>
  struct StringMaker<char[SZ]>
  {
    static std::string convert(char const *str)
    {
      return ::Catch::Detail::stringify(std::string { str });
    }
  };
  template<int SZ>
  struct StringMaker<signed char[SZ]>
  {
    static std::string convert(signed char const *str)
    {
      return ::Catch::Detail::stringify(std::string { reinterpret_cast<char const *>(str) });
    }
  };
  template<int SZ>
  struct StringMaker<unsigned char[SZ]>
  {
    static std::string convert(unsigned char const *str)
    {
      return ::Catch::Detail::stringify(std::string { reinterpret_cast<char const *>(str) });
    }
  };

  template<>
  struct StringMaker<int>
  {
    static std::string convert(int value);
  };
  template<>
  struct StringMaker<long>
  {
    static std::string convert(long value);
  };
  template<>
  struct StringMaker<long long>
  {
    static std::string convert(long long value);
  };
  template<>
  struct StringMaker<unsigned int>
  {
    static std::string convert(unsigned int value);
  };
  template<>
  struct StringMaker<unsigned long>
  {
    static std::string convert(unsigned long value);
  };
  template<>
  struct StringMaker<unsigned long long>
  {
    static std::string convert(unsigned long long value);
  };

  template<>
  struct StringMaker<bool>
  {
    static std::string convert(bool b);
  };

  template<>
  struct StringMaker<char>
  {
    static std::string convert(char c);
  };
  template<>
  struct StringMaker<signed char>
  {
    static std::string convert(signed char c);
  };
  template<>
  struct StringMaker<unsigned char>
  {
    static std::string convert(unsigned char c);
  };

  template<>
  struct StringMaker<std::nullptr_t>
  {
    static std::string convert(std::nullptr_t);
  };

  template<>
  struct StringMaker<float>
  {
    static std::string convert(float value);
  };
  template<>
  struct StringMaker<double>
  {
    static std::string convert(double value);
  };

  template <typename T>
  struct StringMaker<T *>
  {
    template <typename U>
    static std::string convert(U *p)
    {
      if (p)
        {
          return ::Catch::Detail::rawMemoryToString(p);
        }
      else
        {
          return "nullptr";
        }
    }
  };

  template <typename R, typename C>
  struct StringMaker<R C::*>
  {
    static std::string convert(R C::* p)
    {
      if (p)
        {
          return ::Catch::Detail::rawMemoryToString(p);
        }
      else
        {
          return "nullptr";
        }
    }
  };

#if defined(_MANAGED)
  template <typename T>
  struct StringMaker<T ^>
  {
    static std::string convert( T ^ref )
    {
      return ::Catch::Detail::clrReferenceToString(ref);
    }
  };
#endif

  namespace Detail
  {
    template<typename InputIterator>
    std::string rangeToString(InputIterator first, InputIterator last)
    {
      ReusableStringStream rss;
      rss << "{ ";
      if (first != last)
        {
          rss << ::Catch::Detail::stringify(*first);
          for (++first; first != last; ++first)
            rss << ", " << ::Catch::Detail::stringify(*first);
        }
      rss << " }";
      return rss.str();
    }
  }

#ifdef __OBJC__
  template<>
  struct StringMaker<NSString *>
  {
    static std::string convert(NSString *nsstring)
    {
      if (!nsstring)
        return "nil";
      return std::string("@") + [nsstring UTF8String];
    }
  };
  template<>
  struct StringMaker<NSObject *>
  {
    static std::string convert(NSObject *nsObject)
    {
      return ::Catch::Detail::stringify([nsObject description]);
    }

  };
  namespace Detail
  {
    inline std::string stringify( NSString *nsstring )
    {
      return StringMaker<NSString *>::convert( nsstring );
    }

  } // namespace Detail
#endif // __OBJC__

} // namespace Catch

//////////////////////////////////////////////////////
// Separate std-lib types stringification, so it can be selectively enabled
// This means that we do not bring in

#if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
#  define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
#  define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
#  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
#endif

// Separate std::pair specialization
#if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)
#include <utility>
namespace Catch
{
  template<typename T1, typename T2>
  struct StringMaker<std::pair<T1, T2> >
  {
    static std::string convert(const std::pair<T1, T2> &pair)
    {
      ReusableStringStream rss;
      rss << "{ "
          << ::Catch::Detail::stringify(pair.first)
          << ", "
          << ::Catch::Detail::stringify(pair.second)
          << " }";
      return rss.str();
    }
  };
}
#endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER

// Separate std::tuple specialization
#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
#include <tuple>
namespace Catch
{
  namespace Detail
  {
    template<
      typename Tuple,
      std::size_t N = 0,
      bool = (N < std::tuple_size<Tuple>::value)
              >
      struct TupleElementPrinter
      {
        static void print(const Tuple &tuple, std::ostream &os)
    {
      os << (N ? ", " : " ")
          << ::Catch::Detail::stringify(std::get<N>(tuple));
          TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
    }
                           };

    template<
      typename Tuple,
      std::size_t N
      >
    struct TupleElementPrinter<Tuple, N, false>
    {
    static void print(const Tuple &, std::ostream &) {}
    };

  }

  template<typename ...Types>
  struct StringMaker<std::tuple<Types...>>
  {
    static std::string convert(const std::tuple<Types...> &tuple)
  {
    ReusableStringStream rss;
    rss << '{';
    Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
    rss << " }";
    return rss.str();
  }
      };
}
#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER

namespace Catch
{
  struct not_this_one {}; // Tag type for detecting which begin/ end are being selected

  // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace
  using std::begin;
  using std::end;

  not_this_one begin( ... );
  not_this_one end( ... );

  template <typename T>
  struct is_range
  {
    static const bool value =
    !std::is_same<decltype(begin(std::declval<T>())), not_this_one>::value &&
    !std::is_same<decltype(end(std::declval<T>())), not_this_one>::value;
                          };

#if defined(_MANAGED) // Managed types are never ranges
  template <typename T>
  struct is_range<T ^>
  {
    static const bool value = false;
  };
#endif

  template<typename Range>
  std::string rangeToString( Range const &range )
  {
    return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
  }

  // Handle vector<bool> specially
  template<typename Allocator>
  std::string rangeToString( std::vector<bool, Allocator> const &v )
  {
    ReusableStringStream rss;
    rss << "{ ";
    bool first = true;
    for ( bool b : v )
      {
        if ( first )
          first = false;
        else
          rss << ", ";
        rss << ::Catch::Detail::stringify( b );
      }
    rss << " }";
    return rss.str();
  }

  template<typename R>
  struct StringMaker<R, typename std::enable_if<is_range<R>::value  &&!::Catch::Detail::IsStreamInsertable<R>::value>::type>
  {
    static std::string convert( R const &range )
  {
    return rangeToString( range );
  }
  };

  template <typename T, int SZ>
  struct StringMaker<T[SZ]>
  {
    static std::string convert(T const(&arr)[SZ])
  {
    return rangeToString(arr);
  }
  };

} // namespace Catch

// Separate std::chrono::duration specialization
#if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
#include <ctime>
#include <ratio>
#include <chrono>

namespace Catch
{

  template <class Ratio>
  struct ratio_string
  {
    static std::string symbol();
  };

  template <class Ratio>
  std::string ratio_string<Ratio>::symbol()
  {
    Catch::ReusableStringStream rss;
    rss << '[' << Ratio::num << '/'
                              << Ratio::den << ']';
                               return rss.str();
  }
                             template <>
                             struct ratio_string<std::atto>
                             {
                               static std::string symbol();
                             };
                            template <>
                            struct ratio_string<std::femto>
                            {
                              static std::string symbol();
                            };
                            template <>
                            struct ratio_string<std::pico>
                            {
                              static std::string symbol();
                            };
                            template <>
                            struct ratio_string<std::nano>
                            {
                              static std::string symbol();
                            };
                            template <>
                            struct ratio_string<std::micro>
                            {
                              static std::string symbol();
                            };
                            template <>
                            struct ratio_string<std::milli>
                            {
                              static std::string symbol();
                            };

                            ////////////
                            // std::chrono::duration specializations
                            template<typename Value, typename Ratio>
                            struct StringMaker<std::chrono::duration<Value, Ratio>>
                            {
                              static std::string convert(std::chrono::duration<Value, Ratio> const &duration)
  {
    ReusableStringStream rss;
    rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';
                                    return rss.str();
  }
                                                                  };
       template<typename Value>
       struct StringMaker<std::chrono::duration<Value, std::ratio<1>>>
                                                {
                                                  static std::string convert(std::chrono::duration<Value, std::ratio<1>> const &duration)
  {
    ReusableStringStream rss;
    rss << duration.count() << " s";
         return rss.str();
  }
                          };
  template<typename Value>
  struct StringMaker<std::chrono::duration<Value, std::ratio<60>>>
                                           {
                                             static std::string convert(std::chrono::duration<Value, std::ratio<60>> const &duration)
  {
    ReusableStringStream rss;
    rss << duration.count() << " m";
         return rss.str();
  }
                          };
  template<typename Value>
  struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>>
                                           {
                                             static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const &duration)
  {
    ReusableStringStream rss;
    rss << duration.count() << " h";
         return rss.str();
  }
                          };

  ////////////
  // std::chrono::time_point specialization
  // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>
  template<typename Clock, typename Duration>
  struct StringMaker<std::chrono::time_point<Clock, Duration>>
  {
    static std::string convert(std::chrono::time_point<Clock, Duration> const &time_point)
  {
    return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch";
  }
                              };
  // std::chrono::time_point<system_clock> specialization
  template<typename Duration>
  struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>>
  {
    static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const &time_point)
  {
    auto converted = std::chrono::system_clock::to_time_t(time_point);

#ifdef _MSC_VER
    std::tm timeInfo = {};
    gmtime_s(&timeInfo, &converted);
#else
    std::tm *timeInfo = std::gmtime(&converted);
#endif

    auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
    char timeStamp[timeStampSize];
    const char *const fmt = "%Y-%m-%dT%H:%M:%SZ";

#ifdef _MSC_VER
    std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
#else
    std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
#endif
    return std::string(timeStamp);
  }
                              };
}
#endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER

#ifdef _MSC_VER
#pragma warning(pop)
#endif

// end catch_tostring.h
#include <iosfwd>

#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
#pragma warning(disable:4018) // more "signed/unsigned mismatch"
#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
#pragma warning(disable:4180) // qualifier applied to function type has no meaning
#endif

namespace Catch
{

  struct ITransientExpression
  {
    auto isBinaryExpression() const -> bool
  {
    return m_isBinaryExpression;
  }
  auto getResult() const -> bool
  {
    return m_result;
  }
  virtual void streamReconstructedExpression( std::ostream &os ) const = 0;

  ITransientExpression( bool isBinaryExpression, bool result )
  :   m_isBinaryExpression( isBinaryExpression ),
  m_result( result )
  {}

  // We don't actually need a virtual destructor, but many static analysers
  // complain if it's not here :-(
  virtual ~ITransientExpression();

  bool m_isBinaryExpression;
  bool m_result;

  };

  void formatReconstructedExpression( std::ostream &os, std::string const &lhs, StringRef op, std::string const &rhs );

  template<typename LhsT, typename RhsT>
class BinaryExpr  : public ITransientExpression
  {
    LhsT m_lhs;
    StringRef m_op;
    RhsT m_rhs;

    void streamReconstructedExpression( std::ostream &os ) const override
  {
    formatReconstructedExpression
    ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
  }

  public:
  BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
  :   ITransientExpression { true, comparisonResult },
  m_lhs( lhs ),
  m_op( op ),
  m_rhs( rhs )
  {}
  };

  template<typename LhsT>
class UnaryExpr : public ITransientExpression
  {
    LhsT m_lhs;

    void streamReconstructedExpression( std::ostream &os ) const override
  {
    os << Catch::Detail::stringify( m_lhs );
  }

  public:
  explicit UnaryExpr( LhsT lhs )
  :   ITransientExpression { false, lhs ? true : false },
  m_lhs( lhs )
  {}
     };

  // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
  template<typename LhsT, typename RhsT>
  auto compareEqual( LhsT const &lhs, RhsT const &rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
  template<typename T>
  auto compareEqual( T *const &lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const *>( rhs ); }
  template<typename T>
  auto compareEqual( T *const &lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const *>( rhs ); }
  template<typename T>
  auto compareEqual( int lhs, T *const &rhs ) -> bool { return reinterpret_cast<void const *>( lhs ) == rhs; }
  template<typename T>
  auto compareEqual( long lhs, T *const &rhs ) -> bool { return reinterpret_cast<void const *>( lhs ) == rhs; }

  template<typename LhsT, typename RhsT>
  auto compareNotEqual( LhsT const &lhs, RhsT &&rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
  template<typename T>
  auto compareNotEqual( T *const &lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const *>( rhs ); }
  template<typename T>
  auto compareNotEqual( T *const &lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const *>( rhs ); }
  template<typename T>
  auto compareNotEqual( int lhs, T *const &rhs ) -> bool { return reinterpret_cast<void const *>( lhs ) != rhs; }
  template<typename T>
  auto compareNotEqual( long lhs, T *const &rhs ) -> bool { return reinterpret_cast<void const *>( lhs ) != rhs; }

  template<typename LhsT>
  class ExprLhs
  {
    LhsT m_lhs;
    public:
  explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}

  template<typename RhsT>
  auto operator == ( RhsT const &rhs ) -> BinaryExpr<LhsT, RhsT const &> const
  {
    return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs };
  }
  auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const
  {
    return { m_lhs == rhs, m_lhs, "==", rhs };
  }

  template<typename RhsT>
  auto operator != ( RhsT const &rhs ) -> BinaryExpr<LhsT, RhsT const &> const
  {
    return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs };
  }
  auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const
  {
    return { m_lhs != rhs, m_lhs, "!=", rhs };
  }

  template<typename RhsT>
  auto operator > ( RhsT const &rhs ) -> BinaryExpr<LhsT, RhsT const &> const
  {
    return { static_cast<bool>(m_lhs > rhs), m_lhs, ">", rhs };
  }
  template<typename RhsT>
  auto operator < ( RhsT const &rhs ) -> BinaryExpr<LhsT, RhsT const &> const
  {
    return { static_cast<bool>(m_lhs < rhs), m_lhs, "<", rhs };
  }
  template<typename RhsT>
  auto operator >= ( RhsT const &rhs ) -> BinaryExpr<LhsT, RhsT const &> const
  {
    return { static_cast<bool>(m_lhs >= rhs), m_lhs, ">=", rhs };
  }
  template<typename RhsT>
  auto operator <= ( RhsT const &rhs ) -> BinaryExpr<LhsT, RhsT const &> const
  {
    return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
  }

  auto makeUnaryExpr() const -> UnaryExpr<LhsT>
  {
    return UnaryExpr<LhsT>{ m_lhs };
  }
                  };

  void handleExpression( ITransientExpression const &expr );

  template<typename T>
  void handleExpression( ExprLhs<T> const &expr )
  {
    handleExpression( expr.makeUnaryExpr() );
  }

  struct Decomposer
  {
    template<typename T>
    auto operator <= ( T const &lhs ) -> ExprLhs<T const &>
  {
    return ExprLhs<T const &>{ lhs };
  }

  auto operator <=( bool value ) -> ExprLhs<bool>
  {
    return ExprLhs<bool>{ value };
  }
                };

} // end namespace Catch

#ifdef _MSC_VER
#pragma warning(pop)
#endif

// end catch_decomposer.h
// start catch_interfaces_capture.h

#include <string>

namespace Catch
{

  class AssertionResult;
  struct AssertionInfo;
  struct SectionInfo;
  struct SectionEndInfo;
  struct MessageInfo;
  struct Counts;
  struct BenchmarkInfo;
  struct BenchmarkStats;
  struct AssertionReaction;

  struct ITransientExpression;

  struct IResultCapture
  {

    virtual ~IResultCapture();

    virtual bool sectionStarted(    SectionInfo const &sectionInfo,
                                    Counts &assertions ) = 0;
    virtual void sectionEnded( SectionEndInfo const &endInfo ) = 0;
    virtual void sectionEndedEarly( SectionEndInfo const &endInfo ) = 0;

    virtual void benchmarkStarting( BenchmarkInfo const &info ) = 0;
    virtual void benchmarkEnded( BenchmarkStats const &stats ) = 0;

    virtual void pushScopedMessage( MessageInfo const &message ) = 0;
    virtual void popScopedMessage( MessageInfo const &message ) = 0;

    virtual void handleFatalErrorCondition( StringRef message ) = 0;

    virtual void handleExpr
    (   AssertionInfo const &info,
        ITransientExpression const &expr,
        AssertionReaction &reaction ) = 0;
    virtual void handleMessage
    (   AssertionInfo const &info,
        ResultWas::OfType resultType,
        StringRef const &message,
        AssertionReaction &reaction ) = 0;
    virtual void handleUnexpectedExceptionNotThrown
    (   AssertionInfo const &info,
        AssertionReaction &reaction ) = 0;
    virtual void handleUnexpectedInflightException
    (   AssertionInfo const &info,
        std::string const &message,
        AssertionReaction &reaction ) = 0;
    virtual void handleIncomplete
    (   AssertionInfo const &info ) = 0;
    virtual void handleNonExpr
    (   AssertionInfo const &info,
        ResultWas::OfType resultType,
        AssertionReaction &reaction ) = 0;

    virtual bool lastAssertionPassed() = 0;
    virtual void assertionPassed() = 0;

    // Deprecated, do not use:
    virtual std::string getCurrentTestName() const = 0;
    virtual const AssertionResult *getLastResult() const = 0;
    virtual void exceptionEarlyReported() = 0;
  };

  IResultCapture &getResultCapture();
}

// end catch_interfaces_capture.h
namespace Catch
{

  struct TestFailureException {};
  struct AssertionResultData;
  struct IResultCapture;
  class RunContext;

  class LazyExpression
  {
    friend class AssertionHandler;
    friend struct AssertionStats;
    friend class RunContext;

    ITransientExpression const *m_transientExpression = nullptr;
    bool m_isNegated;
    public:
    LazyExpression( bool isNegated );
    LazyExpression( LazyExpression const &other );
    LazyExpression &operator = ( LazyExpression const &) = delete;

    explicit operator bool() const;

    friend auto operator << ( std::ostream &os, LazyExpression const &lazyExpr ) -> std::ostream &;
                         };

  struct AssertionReaction
  {
    bool shouldDebugBreak = false;
    bool shouldThrow = false;
  };

  class AssertionHandler
  {
    AssertionInfo m_assertionInfo;
    AssertionReaction m_reaction;
    bool m_completed = false;
    IResultCapture &m_resultCapture;

    public:
    AssertionHandler
    (   StringRef macroName,
        SourceLineInfo const &lineInfo,
        StringRef capturedExpression,
        ResultDisposition::Flags resultDisposition );
    ~AssertionHandler()
  {
    if ( !m_completed )
      {
        m_resultCapture.handleIncomplete( m_assertionInfo );
      }
  }

  template<typename T>
  void handleExpr( ExprLhs<T> const &expr )
  {
    handleExpr( expr.makeUnaryExpr() );
  }
  void handleExpr( ITransientExpression const &expr );

  void handleMessage(ResultWas::OfType resultType, StringRef const &message);

  void handleExceptionThrownAsExpected();
  void handleUnexpectedExceptionNotThrown();
  void handleExceptionNotThrownAsExpected();
  void handleThrowingCallSkipped();
  void handleUnexpectedInflightException();

  void complete();
  void setCompleted();

  // query
  auto allowThrows() const -> bool;
                 };

  void handleExceptionMatchExpr( AssertionHandler &handler, std::string const &str, StringRef matcherString );

} // namespace Catch

// end catch_assertionhandler.h
// start catch_message.h

#include <string>

namespace Catch
{

  struct MessageInfo
  {
    MessageInfo(    std::string const &_macroName,
                    SourceLineInfo const &_lineInfo,
                    ResultWas::OfType _type );

    std::string macroName;
    std::string message;
    SourceLineInfo lineInfo;
    ResultWas::OfType type;
    unsigned int sequence;

    bool operator == ( MessageInfo const &other ) const;
    bool operator < ( MessageInfo const &other ) const;
                    private:
                    static unsigned int globalCount;
                  };

  struct MessageStream
  {

    template<typename T>
    MessageStream &operator << ( T const &value )
  {
    m_stream << value;
    return *this;
  }

  ReusableStringStream m_stream;
           };

struct MessageBuilder : MessageStream
  {
    MessageBuilder( std::string const &macroName,
                    SourceLineInfo const &lineInfo,
                    ResultWas::OfType type );

    template<typename T>
    MessageBuilder &operator << ( T const &value )
  {
    m_stream << value;
    return *this;
  }

  MessageInfo m_info;
           };

  class ScopedMessage
  {
    public:
    explicit ScopedMessage( MessageBuilder const &builder );
    ~ScopedMessage();

    MessageInfo m_info;
  };

} // end namespace Catch

// end catch_message.h
#if !defined(CATCH_CONFIG_DISABLE)

#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)
#define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__
#else
#define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
#endif

#if defined(CATCH_CONFIG_FAST_COMPILE)

///////////////////////////////////////////////////////////////////////////////
// Another way to speed-up compilation is to omit local try-catch for REQUIRE*
// macros.
#define INTERNAL_CATCH_TRY
#define INTERNAL_CATCH_CATCH( capturer )

#else // CATCH_CONFIG_FAST_COMPILE

#define INTERNAL_CATCH_TRY try
#define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }

#endif

#define INTERNAL_CATCH_REACT( handler ) handler.complete();

///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
  do { \
      Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
      INTERNAL_CATCH_TRY { \
        CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
        catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
        CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
      } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
      INTERNAL_CATCH_REACT( catchAssertionHandler ) \
    } while( (void)0, false && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look
// The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.

///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
  INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
  if( Catch::getResultCapture().lastAssertionPassed() )

///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
  INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
  if( !Catch::getResultCapture().lastAssertionPassed() )

///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
  do { \
      Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
      try { \
          static_cast<void>(__VA_ARGS__); \
          catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
        } \
      catch( ... ) { \
          catchAssertionHandler.handleUnexpectedInflightException(); \
        } \
      INTERNAL_CATCH_REACT( catchAssertionHandler ) \
    } while( false )

///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
  do { \
      Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
      if( catchAssertionHandler.allowThrows() ) \
        try { \
            static_cast<void>(__VA_ARGS__); \
            catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
          } \
        catch( ... ) { \
            catchAssertionHandler.handleExceptionThrownAsExpected(); \
          } \
      else \
        catchAssertionHandler.handleThrowingCallSkipped(); \
      INTERNAL_CATCH_REACT( catchAssertionHandler ) \
    } while( false )

///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
  do { \
      Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
      if( catchAssertionHandler.allowThrows() ) \
        try { \
            static_cast<void>(expr); \
            catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
          } \
        catch( exceptionType const& ) { \
            catchAssertionHandler.handleExceptionThrownAsExpected(); \
          } \
        catch( ... ) { \
            catchAssertionHandler.handleUnexpectedInflightException(); \
          } \
      else \
        catchAssertionHandler.handleThrowingCallSkipped(); \
      INTERNAL_CATCH_REACT( catchAssertionHandler ) \
    } while( false )

///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
  do { \
      Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
      catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
      INTERNAL_CATCH_REACT( catchAssertionHandler ) \
    } while( false )

///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_INFO( macroName, log ) \
  Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );

///////////////////////////////////////////////////////////////////////////////
// Although this is matcher-based, it can be used with just a string
#define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
  do { \
      Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
      if( catchAssertionHandler.allowThrows() ) \
        try { \
            static_cast<void>(__VA_ARGS__); \
            catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
          } \
        catch( ... ) { \
            Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher ); \
          } \
      else \
        catchAssertionHandler.handleThrowingCallSkipped(); \
      INTERNAL_CATCH_REACT( catchAssertionHandler ) \
    } while( false )

#endif // CATCH_CONFIG_DISABLE

// end catch_capture.hpp
// start catch_section.h

// start catch_section_info.h

// start catch_totals.h

#include <cstddef>

namespace Catch
{

  struct Counts
  {
    Counts operator - ( Counts const &other ) const;
    Counts &operator += ( Counts const &other );

    std::size_t total() const;
    bool allPassed() const;
    bool allOk() const;

    std::size_t passed = 0;
    std::size_t failed = 0;
    std::size_t failedButOk = 0;
  };

  struct Totals
  {

    Totals operator - ( Totals const &other ) const;
    Totals &operator += ( Totals const &other );

    Totals delta( Totals const &prevTotals ) const;

    int error = 0;
    Counts assertions;
    Counts testCases;
  };
}

// end catch_totals.h
#include <string>

namespace Catch
{

  struct SectionInfo
  {
    SectionInfo
    (   SourceLineInfo const &_lineInfo,
        std::string const &_name,
        std::string const &_description = std::string() );

    std::string name;
    std::string description;
    SourceLineInfo lineInfo;
  };

  struct SectionEndInfo
  {
    SectionEndInfo( SectionInfo const &_sectionInfo, Counts const &_prevAssertions, double _durationInSeconds );

    SectionInfo sectionInfo;
    Counts prevAssertions;
    double durationInSeconds;
  };

} // end namespace Catch

// end catch_section_info.h
// start catch_timer.h

#include <cstdint>

namespace Catch
{

  auto getCurrentNanosecondsSinceEpoch() -> uint64_t;
  auto getEstimatedClockResolution() -> uint64_t;

  class Timer
  {
    uint64_t m_nanoseconds = 0;
    public:
    void start();
    auto getElapsedNanoseconds() const -> uint64_t;
    auto getElapsedMicroseconds() const -> uint64_t;
    auto getElapsedMilliseconds() const -> unsigned int;
    auto getElapsedSeconds() const -> double;
  };

} // namespace Catch

// end catch_timer.h
#include <string>

namespace Catch
{

class Section : NonCopyable
  {
    public:
    Section( SectionInfo const &info );
    ~Section();

    // This indicates whether the section should be executed or not
    explicit operator bool() const;

    private:
    SectionInfo m_info;

    std::string m_name;
    Counts m_assertions;
    bool m_sectionIncluded;
    Timer m_timer;
  };

} // end namespace Catch

#define INTERNAL_CATCH_SECTION( ... ) \
  if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )

// end catch_section.h
// start catch_benchmark.h

#include <cstdint>
#include <string>

namespace Catch
{

  class BenchmarkLooper
  {

    std::string m_name;
    std::size_t m_count = 0;
    std::size_t m_iterationsToRun = 1;
    uint64_t m_resolution;
    Timer m_timer;

    static auto getResolution() -> uint64_t;
    public:
    // Keep most of this inline as it's on the code path that is being timed
    BenchmarkLooper( StringRef name )
    :   m_name( name ),
    m_resolution( getResolution() )
  {
    reportStart();
    m_timer.start();
  }

  explicit operator bool()
  {
    if ( m_count < m_iterationsToRun )
           return true;
    return needsMoreIterations();
  }

  void increment()
  {
    ++m_count;
  }

  void reportStart();
  auto needsMoreIterations() -> bool;
     };

} // end namespace Catch

#define BENCHMARK( name ) \
  for( Catch::BenchmarkLooper looper( name ); looper; looper.increment() )

// end catch_benchmark.h
// start catch_interfaces_exception.h

// start catch_interfaces_registry_hub.h

#include <string>
#include <memory>

namespace Catch
{

  class TestCase;
  struct ITestCaseRegistry;
  struct IExceptionTranslatorRegistry;
  struct IExceptionTranslator;
  struct IReporterRegistry;
  struct IReporterFactory;
  struct ITagAliasRegistry;
  class StartupExceptionRegistry;

  using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;

  struct IRegistryHub
  {
    virtual ~IRegistryHub();

    virtual IReporterRegistry const &getReporterRegistry() const = 0;
    virtual ITestCaseRegistry const &getTestCaseRegistry() const = 0;
    virtual ITagAliasRegistry const &getTagAliasRegistry() const = 0;

    virtual IExceptionTranslatorRegistry &getExceptionTranslatorRegistry() = 0;

    virtual StartupExceptionRegistry const &getStartupExceptionRegistry() const = 0;
  };

  struct IMutableRegistryHub
  {
    virtual ~IMutableRegistryHub();
    virtual void registerReporter( std::string const &name, IReporterFactoryPtr const &factory ) = 0;
    virtual void registerListener( IReporterFactoryPtr const &factory ) = 0;
    virtual void registerTest( TestCase const &testInfo ) = 0;
    virtual void registerTranslator( const IExceptionTranslator *translator ) = 0;
    virtual void registerTagAlias( std::string const &alias, std::string const &tag, SourceLineInfo const &lineInfo ) = 0;
    virtual void registerStartupException() noexcept = 0;
  };

  IRegistryHub &getRegistryHub();
  IMutableRegistryHub &getMutableRegistryHub();
  void cleanUp();
  std::string translateActiveException();

}

// end catch_interfaces_registry_hub.h
#if defined(CATCH_CONFIG_DISABLE)
#define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \
  static std::string translatorName( signature )
#endif

#include <exception>
#include <string>
#include <vector>

namespace Catch
{
  using exceptionTranslateFunction = std::string(*)();

  struct IExceptionTranslator;
  using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;

  struct IExceptionTranslator
  {
    virtual ~IExceptionTranslator();
    virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
  };

  struct IExceptionTranslatorRegistry
  {
    virtual ~IExceptionTranslatorRegistry();

    virtual std::string translateActiveException() const = 0;
  };

  class ExceptionTranslatorRegistrar
  {
    template<typename T>
    class ExceptionTranslator : public IExceptionTranslator
    {
      public:

      ExceptionTranslator( std::string(*translateFunction)( T &) )
      : m_translateFunction( translateFunction )
  {}

  std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override
  {
    try
      {
        if ( it == itEnd )
          std::rethrow_exception(std::current_exception());
        else
          return (*it)->translate( it+1, itEnd );
      }
    catch ( T &ex )
      {
        return m_translateFunction( ex );
      }
  }

  protected:
  std::string(*m_translateFunction)( T &);
    };

  public:
  template<typename T>
  ExceptionTranslatorRegistrar( std::string(*translateFunction)( T &) )
  {
    getMutableRegistryHub().registerTranslator
    ( new ExceptionTranslator<T>( translateFunction ) );
  }
  };
}

///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
  static std::string translatorName( signature ); \
  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
  namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
  static std::string translatorName( signature )

#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )

// end catch_interfaces_exception.h
// start catch_approx.h

#include <type_traits>
#include <stdexcept>

namespace Catch
{
  namespace Detail
  {

    class Approx
    {
      private:
      bool equalityComparisonImpl(double other) const;

      public:
      explicit Approx ( double value );

      static Approx custom();

      template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
      Approx operator()( T const &value )
  {
    Approx approx( static_cast<double>(value) );
    approx.epsilon( m_epsilon );
    approx.margin( m_margin );
    approx.scale( m_scale );
    return approx;
  }

  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  explicit Approx( T const &value ): Approx(static_cast<double>(value))
  {}

  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  friend bool operator == ( const T &lhs, Approx const &rhs )
  {
    auto lhs_v = static_cast<double>(lhs);
    return rhs.equalityComparisonImpl(lhs_v);
  }

  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  friend bool operator == ( Approx const &lhs, const T &rhs )
  {
    return operator==( rhs, lhs );
  }

  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  friend bool operator != ( T const &lhs, Approx const &rhs )
  {
    return !operator==( lhs, rhs );
  }

  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  friend bool operator != ( Approx const &lhs, T const &rhs )
  {
    return !operator==( rhs, lhs );
  }

  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  friend bool operator <= ( T const &lhs, Approx const &rhs )
  {
    return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;
  }

  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  friend bool operator <= ( Approx const &lhs, T const &rhs )
  {
    return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;
  }

  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  friend bool operator >= ( T const &lhs, Approx const &rhs )
  {
    return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;
  }

  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  friend bool operator >= ( Approx const &lhs, T const &rhs )
  {
    return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;
  }

  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  Approx &epsilon( T const &newEpsilon )
  {
    double epsilonAsDouble = static_cast<double>(newEpsilon);
    if ( epsilonAsDouble < 0 || epsilonAsDouble > 1.0 )
      {
        throw std::domain_error
        (   "Invalid Approx::epsilon: " +
            Catch::Detail::stringify( epsilonAsDouble ) +
            ", Approx::epsilon has to be between 0 and 1" );
      }
    m_epsilon = epsilonAsDouble;
    return *this;
  }

  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  Approx &margin( T const &newMargin )
  {
    double marginAsDouble = static_cast<double>(newMargin);
    if ( marginAsDouble < 0 )
      {
        throw std::domain_error
        (   "Invalid Approx::margin: " +
            Catch::Detail::stringify( marginAsDouble ) +
            ", Approx::Margin has to be non-negative." );

      }
    m_margin = marginAsDouble;
    return *this;
  }

  template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
  Approx &scale( T const &newScale )
  {
    m_scale = static_cast<double>(newScale);
    return *this;
  }

  std::string toString() const;

  private:
  double m_epsilon;
  double m_margin;
  double m_scale;
  double m_value;
                       };
                                                                                }

  template<>
  struct StringMaker<Catch::Detail::Approx>
  {
    static std::string convert(Catch::Detail::Approx const &value);
  };

} // end namespace Catch

// end catch_approx.h
// start catch_string_manip.h

#include <string>
#include <iosfwd>

namespace Catch
{

  bool startsWith( std::string const &s, std::string const &prefix );
  bool startsWith( std::string const &s, char prefix );
  bool endsWith( std::string const &s, std::string const &suffix );
  bool endsWith( std::string const &s, char suffix );
  bool contains( std::string const &s, std::string const &infix );
  void toLowerInPlace( std::string &s );
  std::string toLower( std::string const &s );
  std::string trim( std::string const &str );
  bool replaceInPlace( std::string &str, std::string const &replaceThis, std::string const &withThis );

  struct pluralise
  {
    pluralise( std::size_t count, std::string const &label );

    friend std::ostream &operator << ( std::ostream &os, pluralise const &pluraliser );

                                   std::size_t m_count;
                                   std::string m_label;
                                  };
}

// end catch_string_manip.h
#ifndef CATCH_CONFIG_DISABLE_MATCHERS
// start catch_capture_matchers.h

// start catch_matchers.h

#include <string>
#include <vector>

namespace Catch
{
  namespace Matchers
  {
    namespace Impl
    {

      template<typename ArgT> struct MatchAllOf;
      template<typename ArgT> struct MatchAnyOf;
      template<typename ArgT> struct MatchNotOf;

      class MatcherUntypedBase
      {
        public:
        MatcherUntypedBase() = default;
        MatcherUntypedBase ( MatcherUntypedBase const &) = default;
        MatcherUntypedBase &operator = ( MatcherUntypedBase const &) = delete;
        std::string toString() const;

        protected:
        virtual ~MatcherUntypedBase();
        virtual std::string describe() const = 0;
        mutable std::string m_cachedToString;
      };

      template<typename ObjectT>
      struct MatcherMethod
      {
        virtual bool match( ObjectT const &arg ) const = 0;
      };
      template<typename PtrT>
      struct MatcherMethod<PtrT *>
      {
        virtual bool match( PtrT *arg ) const = 0;
      };

      template<typename T>
      struct MatcherBase : MatcherUntypedBase, MatcherMethod<T>
      {

        MatchAllOf<T> operator && ( MatcherBase const &other ) const;
        MatchAnyOf<T> operator || ( MatcherBase const &other ) const;
        MatchNotOf<T> operator ! () const;
                  };

      template<typename ArgT>
      struct MatchAllOf : MatcherBase<ArgT>
  {
    bool match( ArgT const &arg ) const override
    {
      for ( auto matcher : m_matchers )
        {
          if (!matcher->match(arg))
            return false;
        }
      return true;
    }
    std::string describe() const override
    {
      std::string description;
      description.reserve( 4 + m_matchers.size()*32 );
      description += "( ";
      bool first = true;
      for ( auto matcher : m_matchers )
        {
          if ( first )
            first = false;
          else
            description += " and ";
          description += matcher->toString();
        }
      description += " )";
      return description;
    }

    MatchAllOf<ArgT> &operator && ( MatcherBase<ArgT> const &other )
    {
      m_matchers.push_back( &other );
      return *this;
    }

    std::vector<MatcherBase<ArgT> const *> m_matchers;
  };
  template<typename ArgT>
  struct MatchAnyOf : MatcherBase<ArgT>
  {

    bool match( ArgT const &arg ) const override
  {
    for ( auto matcher : m_matchers )
      {
        if (matcher->match(arg))
          return true;
      }
    return false;
  }
  std::string describe() const override
  {
    std::string description;
    description.reserve( 4 + m_matchers.size()*32 );
    description += "( ";
    bool first = true;
    for ( auto matcher : m_matchers )
      {
        if ( first )
          first = false;
        else
          description += " or ";
        description += matcher->toString();
      }
    description += " )";
    return description;
  }

  MatchAnyOf<ArgT> &operator || ( MatcherBase<ArgT> const &other )
  {
    m_matchers.push_back( &other );
    return *this;
  }

  std::vector<MatcherBase<ArgT> const *> m_matchers;
                         };

  template<typename ArgT>
  struct MatchNotOf : MatcherBase<ArgT>
  {

    MatchNotOf( MatcherBase<ArgT> const &underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}

    bool match( ArgT const &arg ) const override
    {
      return !m_underlyingMatcher.match( arg );
    }

    std::string describe() const override
    {
      return "not " + m_underlyingMatcher.toString();
    }
    MatcherBase<ArgT> const &m_underlyingMatcher;
  };

  template<typename T>
  MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const &other ) const
  {
    return MatchAllOf<T>() && *this && other;
  }
  template<typename T>
  MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const &other ) const
  {
    return MatchAnyOf<T>() || *this || other;
  }
  template<typename T>
  MatchNotOf<T> MatcherBase<T>::operator ! () const
  {
    return MatchNotOf<T>( *this );
  }

                   } // namespace Impl

                           } // namespace Matchers

  using namespace Matchers;
  using Matchers::Impl::MatcherBase;

} // namespace Catch

// end catch_matchers.h
// start catch_matchers_floating.h

#include <type_traits>
#include <cmath>

namespace Catch
{
  namespace Matchers
  {

    namespace Floating
    {

      enum class FloatingPointKind : uint8_t;

      struct WithinAbsMatcher : MatcherBase<double>
      {
        WithinAbsMatcher(double target, double margin);
        bool match(double const &matchee) const override;
        std::string describe() const override;
        private:
        double m_target;
        double m_margin;
      };

      struct WithinUlpsMatcher : MatcherBase<double>
  {
    WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType);
    bool match(double const &matchee) const override;
    std::string describe() const override;
  private:
    double m_target;
    int m_ulps;
    FloatingPointKind m_type;
  };

                                            } // namespace Floating

  // The following functions create the actual matcher objects.
  // This allows the types to be inferred
  Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff);
  Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff);
  Floating::WithinAbsMatcher WithinAbs(double target, double margin);

                                           } // namespace Matchers
} // namespace Catch

// end catch_matchers_floating.h
// start catch_matchers_generic.hpp

#include <functional>
#include <string>

namespace Catch
{
  namespace Matchers
  {
    namespace Generic
    {

      namespace Detail
      {
        std::string finalizeDescription(const std::string &desc);
      }

      template <typename T>
      class PredicateMatcher : public MatcherBase<T>
      {
        std::function<bool(T const &)> m_predicate;
        std::string m_description;
        public:

        PredicateMatcher(std::function<bool(T const &)> const &elem, std::string const &descr)
        :m_predicate(std::move(elem)),
        m_description(Detail::finalizeDescription(descr))
  {}

  bool match( T const &item ) const override
  {
    return m_predicate(item);
  }

  std::string describe() const override
  {
    return m_description;
  }
                        };

                     } // namespace Generic

  // The following functions create the actual matcher objects.
  // The user has to explicitly specify type to the function, because
  // infering std::function<bool(T const&)> is hard (but possible) and
  // requires a lot of TMP.
  template<typename T>
  Generic::PredicateMatcher<T> Predicate(std::function<bool(T const &)> const &predicate, std::string const &description = "")
  {
    return Generic::PredicateMatcher<T>(predicate, description);
  }

                                  } // namespace Matchers
} // namespace Catch

// end catch_matchers_generic.hpp
// start catch_matchers_string.h

#include <string>

namespace Catch
{
  namespace Matchers
  {

    namespace StdString
    {

      struct CasedString
      {
        CasedString( std::string const &str, CaseSensitive::Choice caseSensitivity );
        std::string adjustString( std::string const &str ) const;
        std::string caseSensitivitySuffix() const;

        CaseSensitive::Choice m_caseSensitivity;
        std::string m_str;
      };

      struct StringMatcherBase : MatcherBase<std::string>
  {
    StringMatcherBase( std::string const &operation, CasedString const &comparator );
    std::string describe() const override;

    CasedString m_comparator;
    std::string m_operation;
  };

  struct EqualsMatcher : StringMatcherBase
  {
    EqualsMatcher( CasedString const &comparator );
    bool match( std::string const &source ) const override;
  };
  struct ContainsMatcher : StringMatcherBase
  {
    ContainsMatcher( CasedString const &comparator );
    bool match( std::string const &source ) const override;
  };
  struct StartsWithMatcher : StringMatcherBase
  {
    StartsWithMatcher( CasedString const &comparator );
    bool match( std::string const &source ) const override;
  };
  struct EndsWithMatcher : StringMatcherBase
  {
    EndsWithMatcher( CasedString const &comparator );
    bool match( std::string const &source ) const override;
  };

  struct RegexMatcher : MatcherBase<std::string>
  {
    RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity );
    bool match( std::string const &matchee ) const override;
    std::string describe() const override;

    private:
    std::string m_regex;
    CaseSensitive::Choice m_caseSensitivity;
  };

                                   } // namespace StdString

  // The following functions create the actual matcher objects.
  // This allows the types to be inferred

  StdString::EqualsMatcher Equals( std::string const &str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
  StdString::ContainsMatcher Contains( std::string const &str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
  StdString::EndsWithMatcher EndsWith( std::string const &str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
  StdString::StartsWithMatcher StartsWith( std::string const &str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
  StdString::RegexMatcher Matches( std::string const &regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );

                                            } // namespace Matchers
} // namespace Catch

// end catch_matchers_string.h
// start catch_matchers_vector.h

#include <algorithm>

namespace Catch
{
  namespace Matchers
  {

    namespace Vector
    {
      namespace Detail
      {
        template <typename InputIterator, typename T>
        size_t count(InputIterator first, InputIterator last, T const &item)
  {
    size_t cnt = 0;
    for (; first != last; ++first)
      {
        if (*first == item)
          {
            ++cnt;
          }
      }
    return cnt;
  }
  template <typename InputIterator, typename T>
  bool contains(InputIterator first, InputIterator last, T const &item)
  {
    for (; first != last; ++first)
      {
        if (*first == item)
          {
            return true;
          }
      }
    return false;
  }
           }

  template<typename T>
  struct ContainsElementMatcher : MatcherBase<std::vector<T>>
  {

  ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}

  bool match(std::vector<T> const &v) const override
  {
    for (auto const &el : v)
      {
        if (el == m_comparator)
          {
            return true;
          }
      }
    return false;
  }

  std::string describe() const override
  {
    return "Contains: " + ::Catch::Detail::stringify( m_comparator );
  }

  T const &m_comparator;
            };

  template<typename T>
  struct ContainsMatcher : MatcherBase<std::vector<T>>
  {

    ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}

    bool match(std::vector<T> const &v) const override
    {
      // !TBD: see note in EqualsMatcher
      if (m_comparator.size() > v.size())
        return false;
      for (auto const &comparator : m_comparator)
        {
          auto present = false;
          for (const auto &el : v)
            {
              if (el == comparator)
                {
                  present = true;
                  break;
                }
            }
          if (!present)
            {
              return false;
            }
        }
      return true;
    }
    std::string describe() const override
    {
      return "Contains: " + ::Catch::Detail::stringify( m_comparator );
    }

    std::vector<T> const &m_comparator;
  };

  template<typename T>
  struct EqualsMatcher : MatcherBase<std::vector<T>>
  {

  EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}

  bool match(std::vector<T> const &v) const override
  {
    // !TBD: This currently works if all elements can be compared using !=
    // - a more general approach would be via a compare template that defaults
    // to using !=. but could be specialised for, e.g. std::vector<T> etc
    // - then just call that directly
    if (m_comparator.size() != v.size())
      return false;
    for (std::size_t i = 0; i < v.size(); ++i)
           if (m_comparator[i] != v[i])
             return false;
    return true;
  }
  std::string describe() const override
  {
    return "Equals: " + ::Catch::Detail::stringify( m_comparator );
  }
  std::vector<T> const &m_comparator;
             };

  template<typename T>
  struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>>
  {
    UnorderedEqualsMatcher(std::vector<T> const &target) : m_target(target) {}
    bool match(std::vector<T> const &vec) const override
    {
      // Note: This is a reimplementation of std::is_permutation,
      //       because I don't want to include <algorithm> inside the common path
      if (m_target.size() != vec.size())
        {
          return false;
        }
      auto lfirst = m_target.begin(), llast = m_target.end();
      auto rfirst = vec.begin(), rlast = vec.end();
      // Cut common prefix to optimize checking of permuted parts
      while (lfirst != llast && *lfirst != *rfirst)
        {
          ++lfirst;
          ++rfirst;
        }
      if (lfirst == llast)
        {
          return true;
        }

      for (auto mid = lfirst; mid != llast; ++mid)
        {
          // Skip already counted items
          if (Detail::contains(lfirst, mid, *mid))
            {
              continue;
            }
          size_t num_vec = Detail::count(rfirst, rlast, *mid);
          if (num_vec == 0 || Detail::count(lfirst, llast, *mid) != num_vec)
            {
              return false;
            }
        }

      return true;
    }

    std::string describe() const override
    {
      return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
    }
  private:
    std::vector<T> const &m_target;
  };

             } // namespace Vector

  // The following functions create the actual matcher objects.
  // This allows the types to be inferred

  template<typename T>
  Vector::ContainsMatcher<T> Contains( std::vector<T> const &comparator )
  {
    return Vector::ContainsMatcher<T>( comparator );
  }

  template<typename T>
  Vector::ContainsElementMatcher<T> VectorContains( T const &comparator )
  {
    return Vector::ContainsElementMatcher<T>( comparator );
  }

  template<typename T>
  Vector::EqualsMatcher<T> Equals( std::vector<T> const &comparator )
  {
    return Vector::EqualsMatcher<T>( comparator );
  }

  template<typename T>
  Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const &target)
  {
    return Vector::UnorderedEqualsMatcher<T>(target);
  }

                                       } // namespace Matchers
} // namespace Catch

// end catch_matchers_vector.h
namespace Catch
{

  template<typename ArgT, typename MatcherT>
class MatchExpr : public ITransientExpression
  {
    ArgT const &m_arg;
    MatcherT m_matcher;
    StringRef m_matcherString;
    public:
    MatchExpr( ArgT const &arg, MatcherT const &matcher, StringRef matcherString )
    :   ITransientExpression { true, matcher.match( arg ) },
    m_arg( arg ),
    m_matcher( matcher ),
    m_matcherString( matcherString )
  {}

  void streamReconstructedExpression( std::ostream &os ) const override
  {
    auto matcherAsString = m_matcher.toString();
    os << Catch::Detail::stringify( m_arg ) << ' ';
        if ( matcherAsString == Detail::unprintableString )
          os << m_matcherString;
        else
          os << matcherAsString;
  }
         };

      using StringMatcher = Matchers::Impl::MatcherBase<std::string>;

      void handleExceptionMatchExpr( AssertionHandler &handler, StringMatcher const &matcher, StringRef matcherString  );

      template<typename ArgT, typename MatcherT>
      auto makeMatchExpr( ArgT const &arg, MatcherT const &matcher, StringRef matcherString  ) -> MatchExpr<ArgT, MatcherT>
  {
    return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
  }

} // namespace Catch

///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
  do { \
      Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
      INTERNAL_CATCH_TRY { \
        catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher ) ); \
      } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
      INTERNAL_CATCH_REACT( catchAssertionHandler ) \
    } while( false )

///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
  do { \
      Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
      if( catchAssertionHandler.allowThrows() ) \
        try { \
            static_cast<void>(__VA_ARGS__ ); \
            catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
          } \
        catch( exceptionType const& ex ) { \
            catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher ) ); \
          } \
        catch( ... ) { \
            catchAssertionHandler.handleUnexpectedInflightException(); \
          } \
      else \
        catchAssertionHandler.handleThrowingCallSkipped(); \
      INTERNAL_CATCH_REACT( catchAssertionHandler ) \
    } while( false )

// end catch_capture_matchers.h
#endif

// These files are included here so the single_include script doesn't put them
// in the conditionally compiled sections
// start catch_test_case_info.h

#include <string>
#include <vector>
#include <memory>

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
#endif

namespace Catch
{

  struct ITestInvoker;

  struct TestCaseInfo
  {
    enum SpecialProperties
  {
    None = 0,
    IsHidden = 1 << 1,
    ShouldFail = 1 << 2,
    MayFail = 1 << 3,
    Throws = 1 << 4,
    NonPortable = 1 << 5,
    Benchmark = 1 << 6
  };

  TestCaseInfo(   std::string const &_name,
                  std::string const &_className,
                  std::string const &_description,
                  std::vector<std::string> const &_tags,
                  SourceLineInfo const &_lineInfo );

  friend void setTags( TestCaseInfo &testCaseInfo, std::vector<std::string> tags );

  bool isHidden() const;
  bool throws() const;
  bool okToFail() const;
  bool expectedToFail() const;

  std::string tagsAsString() const;

  std::string name;
  std::string className;
  std::string description;
  std::vector<std::string> tags;
  std::vector<std::string> lcaseTags;
  SourceLineInfo lineInfo;
  SpecialProperties properties;
             };

class TestCase : public TestCaseInfo
  {
    public:

    TestCase( ITestInvoker *testCase, TestCaseInfo &&info );

    TestCase withName( std::string const &_newName ) const;

    void invoke() const;

    TestCaseInfo const &getTestCaseInfo() const;

    bool operator == ( TestCase const &other ) const;
    bool operator < ( TestCase const &other ) const;

                    private:
                    std::shared_ptr<ITestInvoker> test;
                                   };

  TestCase makeTestCase(  ITestInvoker *testCase,
                          std::string const &className,
                          NameAndTags const &nameAndTags,
                          SourceLineInfo const &lineInfo );
}

#ifdef __clang__
#pragma clang diagnostic pop
#endif

// end catch_test_case_info.h
// start catch_interfaces_runner.h

namespace Catch
{

  struct IRunner
  {
    virtual ~IRunner();
    virtual bool aborting() const = 0;
  };
}

// end catch_interfaces_runner.h

#ifdef __OBJC__
// start catch_objc.hpp

#import <objc/runtime.h>

#include <string>

// NB. Any general catch headers included here must be included
// in catch.hpp first to make sure they are included by the single
// header for non obj-usage

///////////////////////////////////////////////////////////////////////////////
// This protocol is really only here for (self) documenting purposes, since
// all its methods are optional.
@protocol OcFixture

@optional

-(void) setUp;
-(void) tearDown;

@end

namespace Catch
{

  class OcMethod : public ITestInvoker
  {

    public:
OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}

virtual void invoke() const
{
  id obj = [[m_cls alloc] init];

  performOptionalSelector( obj, @selector(setUp)  );
  performOptionalSelector( obj, m_sel );
  performOptionalSelector( obj, @selector(tearDown)  );

  arcSafeRelease( obj );
}
private:
virtual ~OcMethod() {}

Class m_cls;
SEL m_sel;
  };

namespace Detail
{

  inline std::string getAnnotation(   Class cls,
                                      std::string const &annotationName,
                                      std::string const &testCaseName )
{
  NSString *selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
  SEL sel = NSSelectorFromString( selStr );
  arcSafeRelease( selStr );
  id value = performOptionalSelector( cls, sel );
  if ( value )
    return [(NSString *)value UTF8String];
  return "";
}
}

inline std::size_t registerTestMethods()
{
  std::size_t noTestMethods = 0;
  int noClasses = objc_getClassList( nullptr, 0 );

  Class *classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
  objc_getClassList( classes, noClasses );

  for ( int c = 0; c < noClasses; c++ )
    {
      Class cls = classes[c];
      {
        u_int count;
        Method *methods = class_copyMethodList( cls, &count );
        for ( u_int m = 0; m < count ; m++ )
          {
            SEL selector = method_getName(methods[m]);
            std::string methodName = sel_getName(selector);
            if ( startsWith( methodName, "Catch_TestCase_" ) )
              {
                std::string testCaseName = methodName.substr( 15 );
                std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
                std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
                const char *className = class_getName( cls );

                getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo("",0) ) );
                noTestMethods++;
              }
          }
        free(methods);
      }
    }
  return noTestMethods;
}

#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)

namespace Matchers
{
  namespace Impl
  {
    namespace NSStringMatchers
    {

      struct StringHolder : MatcherBase<NSString *>
      {
StringHolder( NSString *substr ) : m_substr( [substr copy] ) {}
StringHolder( StringHolder const &other ) : m_substr( [other.m_substr copy] ) {}
StringHolder()
{
  arcSafeRelease( m_substr );
}

bool match( NSString *arg ) const override
{
  return false;
}

NSString *CATCH_ARC_STRONG m_substr;
      };

struct Equals : StringHolder
{
Equals( NSString *substr ) : StringHolder( substr ) {}

bool match( NSString *str ) const override
{
  return  (str != nil || m_substr == nil ) &&
  [str isEqualToString:m_substr];
}

std::string describe() const override
{
  return "equals string: " + Catch::Detail::stringify( m_substr );
}
};

struct Contains : StringHolder
{
Contains( NSString *substr ) : StringHolder( substr ) {}

bool match( NSString *str ) const
{
  return  (str != nil || m_substr == nil ) &&
  [str rangeOfString:m_substr].location != NSNotFound;
}

std::string describe() const override
{
  return "contains string: " + Catch::Detail::stringify( m_substr );
}
};

struct StartsWith : StringHolder
{
StartsWith( NSString *substr ) : StringHolder( substr ) {}

bool match( NSString *str ) const override
{
  return  (str != nil || m_substr == nil ) &&
  [str rangeOfString:m_substr].location == 0;
}

std::string describe() const override
{
  return "starts with: " + Catch::Detail::stringify( m_substr );
}
};
struct EndsWith : StringHolder
{
EndsWith( NSString *substr ) : StringHolder( substr ) {}

bool match( NSString *str ) const override
{
  return  (str != nil || m_substr == nil ) &&
  [str rangeOfString:m_substr].location == [str length] - [m_substr length];
}

std::string describe() const override
{
  return "ends with: " + Catch::Detail::stringify( m_substr );
}
};

                                       } // namespace NSStringMatchers
    } // namespace Impl

inline Impl::NSStringMatchers::Equals
Equals( NSString *substr )
{
  return Impl::NSStringMatchers::Equals( substr );
}

inline Impl::NSStringMatchers::Contains
Contains( NSString *substr )
{
  return Impl::NSStringMatchers::Contains( substr );
}

inline Impl::NSStringMatchers::StartsWith
StartsWith( NSString *substr )
{
  return Impl::NSStringMatchers::StartsWith( substr );
}

inline Impl::NSStringMatchers::EndsWith
EndsWith( NSString *substr )
{
  return Impl::NSStringMatchers::EndsWith( substr );
}

  } // namespace Matchers

using namespace Matchers;

#endif // CATCH_CONFIG_DISABLE_MATCHERS

} // namespace Catch

///////////////////////////////////////////////////////////////////////////////
#define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix
#define OC_TEST_CASE2( name, desc, uniqueSuffix ) \
  +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \
  { \
    return @ name; \
  } \
  +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \
  { \
    return @ desc; \
  } \
  -(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )

#define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )

// end catch_objc.hpp
#endif

#ifdef CATCH_CONFIG_EXTERNAL_INTERFACES
// start catch_external_interfaces.h

// start catch_reporter_bases.hpp

// start catch_interfaces_reporter.h

// start catch_config.hpp

// start catch_test_spec_parser.h

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
#endif

// start catch_test_spec.h

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
#endif

// start catch_wildcard_pattern.h

namespace Catch
{
  class WildcardPattern
  {
    enum WildcardPosition
{
  NoWildcard = 0,
  WildcardAtStart = 1,
  WildcardAtEnd = 2,
  WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
};

public:

WildcardPattern( std::string const &pattern, CaseSensitive::Choice caseSensitivity );
virtual ~WildcardPattern() = default;
virtual bool matches( std::string const &str ) const;

private:
std::string adjustCase( std::string const &str ) const;
CaseSensitive::Choice m_caseSensitivity;
WildcardPosition m_wildcard = NoWildcard;
std::string m_pattern;
  };
}

// end catch_wildcard_pattern.h
#include <string>
#include <vector>
#include <memory>

namespace Catch
{

  class TestSpec
  {
    struct Pattern
    {
      virtual ~Pattern();
      virtual bool matches( TestCaseInfo const &testCase ) const = 0;
    };
    using PatternPtr = std::shared_ptr<Pattern>;

    class NamePattern : public Pattern
    {
      public:
      NamePattern( std::string const &name );
      virtual ~NamePattern();
      virtual bool matches( TestCaseInfo const &testCase ) const override;
      private:
      WildcardPattern m_wildcardPattern;
    };

    class TagPattern : public Pattern
{
public:
  TagPattern( std::string const &tag );
  virtual ~TagPattern();
  virtual bool matches( TestCaseInfo const &testCase ) const override;
private:
  std::string m_tag;
};

class ExcludedPattern : public Pattern
{
  public:
  ExcludedPattern( PatternPtr const &underlyingPattern );
  virtual ~ExcludedPattern();
  virtual bool matches( TestCaseInfo const &testCase ) const override;
  private:
  PatternPtr m_underlyingPattern;
};

struct Filter
{
  std::vector<PatternPtr> m_patterns;

  bool matches( TestCaseInfo const &testCase ) const;
};

public:
bool hasFilters() const;
bool matches( TestCaseInfo const &testCase ) const;

private:
std::vector<Filter> m_filters;

friend class TestSpecParser;
           };
           }

#ifdef __clang__
#pragma clang diagnostic pop
#endif

// end catch_test_spec.h
// start catch_interfaces_tag_alias_registry.h

#include <string>

namespace Catch
{

  struct TagAlias;

  struct ITagAliasRegistry
  {
    virtual ~ITagAliasRegistry();
    // Nullptr if not present
    virtual TagAlias const *find( std::string const &alias ) const = 0;
    virtual std::string expandAliases( std::string const &unexpandedTestSpec ) const = 0;

    static ITagAliasRegistry const &get();
  };

} // end namespace Catch

// end catch_interfaces_tag_alias_registry.h
namespace Catch
{

  class TestSpecParser
  {
    enum Mode { None, Name, QuotedName, Tag, EscapedName };
    Mode m_mode = None;
    bool m_exclusion = false;
    std::size_t m_start = std::string::npos, m_pos = 0;
    std::string m_arg;
    std::vector<std::size_t> m_escapeChars;
    TestSpec::Filter m_currentFilter;
    TestSpec m_testSpec;
    ITagAliasRegistry const *m_tagAliases = nullptr;

    public:
    TestSpecParser( ITagAliasRegistry const &tagAliases );

    TestSpecParser &parse( std::string const &arg );
    TestSpec testSpec();

    private:
    void visitChar( char c );
    void startNewMode( Mode mode, std::size_t start );
    void escape();
    std::string subString() const;

    template<typename T>
    void addPattern()
{
  std::string token = subString();
  for ( std::size_t i = 0; i < m_escapeChars.size(); ++i )
          token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 );
  m_escapeChars.clear();
  if ( startsWith( token, "exclude:" ) )
    {
      m_exclusion = true;
      token = token.substr( 8 );
    }
  if ( !token.empty() )
    {
      TestSpec::PatternPtr pattern = std::make_shared<T>( token );
      if ( m_exclusion )
        pattern = std::make_shared<TestSpec::ExcludedPattern>( pattern );
      m_currentFilter.m_patterns.push_back( pattern );
    }
  m_exclusion = false;
  m_mode = None;
}

void addFilter();
                          };
TestSpec parseTestSpec( std::string const &arg );

                                               } // namespace Catch

#ifdef __clang__
#pragma clang diagnostic pop
#endif

// end catch_test_spec_parser.h
// start catch_interfaces_config.h

#include <iosfwd>
#include <string>
#include <vector>
#include <memory>

namespace Catch
{

  enum class Verbosity
  {
    Quiet = 0,
    Normal,
    High
  };

  struct WarnAbout
  {
    enum What
{
  Nothing = 0x00,
  NoAssertions = 0x01,
  NoTests = 0x02
};
  };

struct ShowDurations
{
  enum OrNot
{
  DefaultForReporter,
  Always,
  Never
};
};
struct RunTests
{
  enum InWhatOrder
{
  InDeclarationOrder,
  InLexicographicalOrder,
  InRandomOrder
};
};
struct UseColour
{
  enum YesOrNo
{
  Auto,
  Yes,
  No
};
};
struct WaitForKeypress
{
  enum When
{
  Never,
  BeforeStart = 1,
  BeforeExit = 2,
  BeforeStartAndExit = BeforeStart | BeforeExit
};
};

class TestSpec;

struct IConfig : NonCopyable
{

  virtual ~IConfig();

  virtual bool allowThrows() const = 0;
  virtual std::ostream &stream() const = 0;
  virtual std::string name() const = 0;
  virtual bool includeSuccessfulResults() const = 0;
  virtual bool shouldDebugBreak() const = 0;
  virtual bool warnAboutMissingAssertions() const = 0;
  virtual bool warnAboutNoTests() const = 0;
  virtual int abortAfter() const = 0;
  virtual bool showInvisibles() const = 0;
  virtual ShowDurations::OrNot showDurations() const = 0;
  virtual TestSpec const &testSpec() const = 0;
  virtual bool hasTestFilters() const = 0;
  virtual RunTests::InWhatOrder runOrder() const = 0;
  virtual unsigned int rngSeed() const = 0;
  virtual int benchmarkResolutionMultiple() const = 0;
  virtual UseColour::YesOrNo useColour() const = 0;
  virtual std::vector<std::string> const &getSectionsToRun() const = 0;
  virtual Verbosity verbosity() const = 0;
                     };

using IConfigPtr = std::shared_ptr<IConfig const>;
                                  }

// end catch_interfaces_config.h
// Libstdc++ doesn't like incomplete classes for unique_ptr

#include <memory>
#include <vector>
#include <string>

#ifndef CATCH_CONFIG_CONSOLE_WIDTH
#define CATCH_CONFIG_CONSOLE_WIDTH 80
#endif

namespace Catch
{

  struct IStream;

  struct ConfigData
  {
    bool listTests = false;
    bool listTags = false;
    bool listReporters = false;
    bool listTestNamesOnly = false;

    bool showSuccessfulTests = false;
    bool shouldDebugBreak = false;
    bool noThrow = false;
    bool showHelp = false;
    bool showInvisibles = false;
    bool filenamesAsTags = false;
    bool libIdentify = false;

    int abortAfter = -1;
    unsigned int rngSeed = 0;
    int benchmarkResolutionMultiple = 100;

    Verbosity verbosity = Verbosity::Normal;
    WarnAbout::What warnings = WarnAbout::Nothing;
    ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
    RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
    UseColour::YesOrNo useColour = UseColour::Auto;
    WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;

    std::string outputFilename;
    std::string name;
    std::string processName;
#ifndef CATCH_CONFIG_DEFAULT_REPORTER
#define CATCH_CONFIG_DEFAULT_REPORTER "console"
#endif
    std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;
#undef CATCH_CONFIG_DEFAULT_REPORTER

    std::vector<std::string> testsOrTags;
    std::vector<std::string> sectionsToRun;
               };

class Config : public IConfig
  {
    public:

    Config() = default;
    Config( ConfigData const &data );
    virtual ~Config() = default;

    std::string const &getFilename() const;

    bool listTests() const;
    bool listTestNamesOnly() const;
    bool listTags() const;
    bool listReporters() const;

    std::string getProcessName() const;
    std::string const &getReporterName() const;

    std::vector<std::string> const &getTestsOrTags() const;
    std::vector<std::string> const &getSectionsToRun() const override;

    virtual TestSpec const &testSpec() const override;
    bool hasTestFilters() const override;

    bool showHelp() const;

    // IConfig interface
    bool allowThrows() const override;
    std::ostream &stream() const override;
    std::string name() const override;
    bool includeSuccessfulResults() const override;
    bool warnAboutMissingAssertions() const override;
    bool warnAboutNoTests() const override;
    ShowDurations::OrNot showDurations() const override;
    RunTests::InWhatOrder runOrder() const override;
    unsigned int rngSeed() const override;
    int benchmarkResolutionMultiple() const override;
    UseColour::YesOrNo useColour() const override;
    bool shouldDebugBreak() const override;
    int abortAfter() const override;
    bool showInvisibles() const override;
    Verbosity verbosity() const override;

    private:

    IStream const *openStream();
    ConfigData m_data;

    std::unique_ptr<IStream const> m_stream;
    TestSpec m_testSpec;
    bool m_hasTestFilters = false;
                   };

} // end namespace Catch

// end catch_config.hpp
// start catch_assertionresult.h

#include <string>

namespace Catch
{

  struct AssertionResultData
  {
    AssertionResultData() = delete;

    AssertionResultData( ResultWas::OfType _resultType, LazyExpression const &_lazyExpression );

    std::string message;
    mutable std::string reconstructedExpression;
    LazyExpression lazyExpression;
    ResultWas::OfType resultType;

    std::string reconstructExpression() const;
  };

  class AssertionResult
{
public:
  AssertionResult() = delete;
  AssertionResult( AssertionInfo const &info, AssertionResultData const &data );

  bool isOk() const;
  bool succeeded() const;
  ResultWas::OfType getResultType() const;
  bool hasExpression() const;
  bool hasMessage() const;
  std::string getExpression() const;
  std::string getExpressionInMacro() const;
  bool hasExpandedExpression() const;
  std::string getExpandedExpression() const;
  std::string getMessage() const;
  SourceLineInfo getSourceInfo() const;
  StringRef getTestMacroName() const;

  //protected:
  AssertionInfo m_info;
  AssertionResultData m_resultData;
};

} // end namespace Catch

// end catch_assertionresult.h
// start catch_option.hpp

namespace Catch
{

  // An optional type
  template<typename T>
  class Option
  {
    public:
Option() : nullableValue( nullptr ) {}
Option( T const &_value )
: nullableValue( new( storage ) T( _value ) )
{}
Option( Option const &_other )
: nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
{}

~Option()
{
  reset();
}

Option &operator= ( Option const &_other )
{
  if ( &_other != this )
    {
      reset();
      if ( _other )
        nullableValue = new( storage ) T( *_other );
    }
  return *this;
}
Option &operator = ( T const &_value )
{
  reset();
  nullableValue = new( storage ) T( _value );
  return *this;
}

void reset()
{
  if ( nullableValue )
    nullableValue->~T();
  nullableValue = nullptr;
}

T &operator*()
{
  return *nullableValue;
}
T const &operator*() const
{
  return *nullableValue;
}
T *operator->()
{
  return nullableValue;
}
const T *operator->() const
{
  return nullableValue;
}

T valueOr( T const &defaultValue ) const
{
  return nullableValue ? *nullableValue : defaultValue;
}

bool some() const
{
  return nullableValue != nullptr;
}
bool none() const
{
  return nullableValue == nullptr;
}

bool operator !() const
{
  return nullableValue == nullptr;
}
explicit operator bool() const
{
  return some();
}

private:
T *nullableValue;
alignas(alignof(T)) char storage[sizeof(T)];
  };

          } // end namespace Catch

// end catch_option.hpp
#include <string>
#include <iosfwd>
#include <map>
#include <set>
#include <memory>

namespace Catch
{

  struct ReporterConfig
  {
    explicit ReporterConfig( IConfigPtr const &_fullConfig );

    ReporterConfig( IConfigPtr const &_fullConfig, std::ostream &_stream );

    std::ostream &stream() const;
    IConfigPtr fullConfig() const;

    private:
    std::ostream *m_stream;
    IConfigPtr m_fullConfig;
  };

  struct ReporterPreferences
{
  bool shouldRedirectStdOut = false;
};

template<typename T>
struct LazyStat : Option<T>
{
  LazyStat &operator=( T const &_value )
{
  Option<T>::operator=( _value );
  used = false;
  return *this;
}
void reset()
{
  Option<T>::reset();
  used = false;
}
bool used = false;
      };

struct TestRunInfo
{
  TestRunInfo( std::string const &_name );
  std::string name;
};
struct GroupInfo
{
  GroupInfo(  std::string const &_name,
              std::size_t _groupIndex,
              std::size_t _groupsCount );

  std::string name;
  std::size_t groupIndex;
  std::size_t groupsCounts;
};

struct AssertionStats
{
  AssertionStats( AssertionResult const &_assertionResult,
                  std::vector<MessageInfo> const &_infoMessages,
                  Totals const &_totals );

  AssertionStats( AssertionStats const &)              = default;
  AssertionStats( AssertionStats &&)                  = default;
  AssertionStats &operator = ( AssertionStats const &) = default;
  AssertionStats &operator = ( AssertionStats && )     = default;
  virtual ~AssertionStats();

  AssertionResult assertionResult;
  std::vector<MessageInfo> infoMessages;
  Totals totals;
             };

struct SectionStats
{
  SectionStats(   SectionInfo const &_sectionInfo,
                  Counts const &_assertions,
                  double _durationInSeconds,
                  bool _missingAssertions );
  SectionStats( SectionStats const &)              = default;
  SectionStats( SectionStats &&)                  = default;
  SectionStats &operator = ( SectionStats const &) = default;
  SectionStats &operator = ( SectionStats && )     = default;
  virtual ~SectionStats();

  SectionInfo sectionInfo;
  Counts assertions;
  double durationInSeconds;
  bool missingAssertions;
};

struct TestCaseStats
{
  TestCaseStats(  TestCaseInfo const &_testInfo,
                  Totals const &_totals,
                  std::string const &_stdOut,
                  std::string const &_stdErr,
                  bool _aborting );

  TestCaseStats( TestCaseStats const &)              = default;
  TestCaseStats( TestCaseStats &&)                  = default;
  TestCaseStats &operator = ( TestCaseStats const &) = default;
  TestCaseStats &operator = ( TestCaseStats && )     = default;
  virtual ~TestCaseStats();

  TestCaseInfo testInfo;
  Totals totals;
  std::string stdOut;
  std::string stdErr;
  bool aborting;
};

struct TestGroupStats
{
  TestGroupStats( GroupInfo const &_groupInfo,
                  Totals const &_totals,
                  bool _aborting );
  TestGroupStats( GroupInfo const &_groupInfo );

  TestGroupStats( TestGroupStats const &)              = default;
  TestGroupStats( TestGroupStats &&)                  = default;
  TestGroupStats &operator = ( TestGroupStats const &) = default;
  TestGroupStats &operator = ( TestGroupStats && )     = default;
  virtual ~TestGroupStats();

  GroupInfo groupInfo;
  Totals totals;
  bool aborting;
};

struct TestRunStats
{
  TestRunStats(   TestRunInfo const &_runInfo,
                  Totals const &_totals,
                  bool _aborting );

  TestRunStats( TestRunStats const &)              = default;
  TestRunStats( TestRunStats &&)                  = default;
  TestRunStats &operator = ( TestRunStats const &) = default;
  TestRunStats &operator = ( TestRunStats && )     = default;
  virtual ~TestRunStats();

  TestRunInfo runInfo;
  Totals totals;
  bool aborting;
};

struct BenchmarkInfo
{
  std::string name;
};
struct BenchmarkStats
{
  BenchmarkInfo info;
  std::size_t iterations;
  uint64_t elapsedTimeInNanoseconds;
};

struct IStreamingReporter
{
  virtual ~IStreamingReporter() = default;

  // Implementing class must also provide the following static methods:
  // static std::string getDescription();
  // static std::set<Verbosity> getSupportedVerbosities()

  virtual ReporterPreferences getPreferences() const = 0;

  virtual void noMatchingTestCases( std::string const &spec ) = 0;

  virtual void testRunStarting( TestRunInfo const &testRunInfo ) = 0;
  virtual void testGroupStarting( GroupInfo const &groupInfo ) = 0;

  virtual void testCaseStarting( TestCaseInfo const &testInfo ) = 0;
  virtual void sectionStarting( SectionInfo const &sectionInfo ) = 0;

  // *** experimental ***
virtual void benchmarkStarting( BenchmarkInfo const &) {}

virtual void assertionStarting( AssertionInfo const &assertionInfo ) = 0;

// The return value indicates if the messages buffer should be cleared:
virtual bool assertionEnded( AssertionStats const &assertionStats ) = 0;

// *** experimental ***
virtual void benchmarkEnded( BenchmarkStats const &) {}

virtual void sectionEnded( SectionStats const &sectionStats ) = 0;
virtual void testCaseEnded( TestCaseStats const &testCaseStats ) = 0;
virtual void testGroupEnded( TestGroupStats const &testGroupStats ) = 0;
virtual void testRunEnded( TestRunStats const &testRunStats ) = 0;

virtual void skipTest( TestCaseInfo const &testInfo ) = 0;

// Default empty implementation provided
virtual void fatalErrorEncountered( StringRef name );

virtual bool isMulti() const;
};
using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;

struct IReporterFactory
{
  virtual ~IReporterFactory();
  virtual IStreamingReporterPtr create( ReporterConfig const &config ) const = 0;
  virtual std::string getDescription() const = 0;
};
using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;

struct IReporterRegistry
{
  using FactoryMap = std::map<std::string, IReporterFactoryPtr>;
  using Listeners = std::vector<IReporterFactoryPtr>;

  virtual ~IReporterRegistry();
  virtual IStreamingReporterPtr create( std::string const &name, IConfigPtr const &config ) const = 0;
  virtual FactoryMap const &getFactories() const = 0;
  virtual Listeners const &getListeners() const = 0;
                               };

                             } // end namespace Catch

// end catch_interfaces_reporter.h
#include <algorithm>
#include <cstring>
#include <cfloat>
#include <cstdio>
#include <cassert>
#include <memory>
#include <ostream>

namespace Catch
{
  void prepareExpandedExpression(AssertionResult &result);

  // Returns double formatted as %.3f (format expected on output)
  std::string getFormattedDuration( double duration );

  template<typename DerivedT>
  struct StreamingReporterBase : IStreamingReporter
  {

    StreamingReporterBase( ReporterConfig const &_config )
    :   m_config( _config.fullConfig() ),
    stream( _config.stream() )
{
  m_reporterPrefs.shouldRedirectStdOut = false;
  if ( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
    throw std::domain_error( "Verbosity level not supported by this reporter" );
}

ReporterPreferences getPreferences() const override
{
  return m_reporterPrefs;
}

static std::set<Verbosity> getSupportedVerbosities()
{
  return { Verbosity::Normal };
}

~StreamingReporterBase() override = default;

void noMatchingTestCases(std::string const &) override {}

void testRunStarting(TestRunInfo const &_testRunInfo) override
{
  currentTestRunInfo = _testRunInfo;
}
void testGroupStarting(GroupInfo const &_groupInfo) override
{
  currentGroupInfo = _groupInfo;
}

void testCaseStarting(TestCaseInfo const &_testInfo) override
{
  currentTestCaseInfo = _testInfo;
}
void sectionStarting(SectionInfo const &_sectionInfo) override
{
  m_sectionStack.push_back(_sectionInfo);
}

void sectionEnded(SectionStats const & /* _sectionStats */) override
{
  m_sectionStack.pop_back();
}
void testCaseEnded(TestCaseStats const & /* _testCaseStats */) override
{
  currentTestCaseInfo.reset();
}
void testGroupEnded(TestGroupStats const & /* _testGroupStats */) override
{
  currentGroupInfo.reset();
}
void testRunEnded(TestRunStats const & /* _testRunStats */) override
{
  currentTestCaseInfo.reset();
  currentGroupInfo.reset();
  currentTestRunInfo.reset();
}

void skipTest(TestCaseInfo const &) override
{
  // Don't do anything with this by default.
  // It can optionally be overridden in the derived class.
}

IConfigPtr m_config;
std::ostream &stream;

LazyStat<TestRunInfo> currentTestRunInfo;
LazyStat<GroupInfo> currentGroupInfo;
LazyStat<TestCaseInfo> currentTestCaseInfo;

std::vector<SectionInfo> m_sectionStack;
ReporterPreferences m_reporterPrefs;
           };

template<typename DerivedT>
struct CumulativeReporterBase : IStreamingReporter
{
  template<typename T, typename ChildNodeT>
  struct Node
  {
explicit Node( T const &_value ) : value( _value ) {}
virtual ~Node() {}

using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;
T value;
ChildNodes children;
                                              };
struct SectionNode
{
explicit SectionNode(SectionStats const &_stats) : stats(_stats) {}
virtual ~SectionNode() = default;

bool operator == (SectionNode const &other) const
{
  return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
}
bool operator == (std::shared_ptr<SectionNode> const &other) const
{
  return operator==(*other);
}

SectionStats stats;
using ChildSections = std::vector<std::shared_ptr<SectionNode>>;
using Assertions = std::vector<AssertionStats>;
ChildSections childSections;
Assertions assertions;
std::string stdOut;
std::string stdErr;
                              };

struct BySectionInfo
{
BySectionInfo( SectionInfo const &other ) : m_other( other ) {}
BySectionInfo( BySectionInfo const &other ) : m_other( other.m_other ) {}
bool operator() (std::shared_ptr<SectionNode> const &node) const
{
  return ((node->stats.sectionInfo.name == m_other.name) &&
          (node->stats.sectionInfo.lineInfo == m_other.lineInfo));
}
void operator=(BySectionInfo const &) = delete;

private:
SectionInfo const &m_other;
                };

using TestCaseNode = Node<TestCaseStats, SectionNode>;
using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
using TestRunNode = Node<TestRunStats, TestGroupNode>;

CumulativeReporterBase( ReporterConfig const &_config )
:   m_config( _config.fullConfig() ),
stream( _config.stream() )
{
  m_reporterPrefs.shouldRedirectStdOut = false;
  if ( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
    throw std::domain_error( "Verbosity level not supported by this reporter" );
}
~CumulativeReporterBase() override = default;

ReporterPreferences getPreferences() const override
{
  return m_reporterPrefs;
}

static std::set<Verbosity> getSupportedVerbosities()
{
  return { Verbosity::Normal };
}

void testRunStarting( TestRunInfo const &) override {}
void testGroupStarting( GroupInfo const &) override {}

void testCaseStarting( TestCaseInfo const &) override {}

void sectionStarting( SectionInfo const &sectionInfo ) override
{
  SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
  std::shared_ptr<SectionNode> node;
  if ( m_sectionStack.empty() )
    {
      if ( !m_rootSection )
        m_rootSection = std::make_shared<SectionNode>( incompleteStats );
      node = m_rootSection;
    }
  else
    {
      SectionNode &parentNode = *m_sectionStack.back();
      auto it =
      std::find_if(   parentNode.childSections.begin(),
                      parentNode.childSections.end(),
                      BySectionInfo( sectionInfo ) );
      if ( it == parentNode.childSections.end() )
        {
          node = std::make_shared<SectionNode>( incompleteStats );
          parentNode.childSections.push_back( node );
        }
      else
        node = *it;
    }
  m_sectionStack.push_back( node );
  m_deepestSection = std::move(node);
}

void assertionStarting(AssertionInfo const &) override {}

bool assertionEnded(AssertionStats const &assertionStats) override
{
  assert(!m_sectionStack.empty());
  // AssertionResult holds a pointer to a temporary DecomposedExpression,
  // which getExpandedExpression() calls to build the expression string.
  // Our section stack copy of the assertionResult will likely outlive the
  // temporary, so it must be expanded or discarded now to avoid calling
  // a destroyed object later.
  prepareExpandedExpression(const_cast<AssertionResult &>( assertionStats.assertionResult ) );
  SectionNode &sectionNode = *m_sectionStack.back();
  sectionNode.assertions.push_back(assertionStats);
  return true;
}
void sectionEnded(SectionStats const &sectionStats) override
{
  assert(!m_sectionStack.empty());
  SectionNode &node = *m_sectionStack.back();
  node.stats = sectionStats;
  m_sectionStack.pop_back();
}
void testCaseEnded(TestCaseStats const &testCaseStats) override
{
  auto node = std::make_shared<TestCaseNode>(testCaseStats);
  assert(m_sectionStack.size() == 0);
  node->children.push_back(m_rootSection);
  m_testCases.push_back(node);
  m_rootSection.reset();

  assert(m_deepestSection);
  m_deepestSection->stdOut = testCaseStats.stdOut;
  m_deepestSection->stdErr = testCaseStats.stdErr;
}
void testGroupEnded(TestGroupStats const &testGroupStats) override
{
  auto node = std::make_shared<TestGroupNode>(testGroupStats);
  node->children.swap(m_testCases);
  m_testGroups.push_back(node);
}
void testRunEnded(TestRunStats const &testRunStats) override
{
  auto node = std::make_shared<TestRunNode>(testRunStats);
  node->children.swap(m_testGroups);
  m_testRuns.push_back(node);
  testRunEndedCumulative();
}
virtual void testRunEndedCumulative() = 0;

void skipTest(TestCaseInfo const &) override {}

IConfigPtr m_config;
std::ostream &stream;
std::vector<AssertionStats> m_assertions;
std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;
                        std::vector<std::shared_ptr<TestCaseNode>> m_testCases;
                        std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;

                        std::vector<std::shared_ptr<TestRunNode>> m_testRuns;

                        std::shared_ptr<SectionNode> m_rootSection;
                        std::shared_ptr<SectionNode> m_deepestSection;
                        std::vector<std::shared_ptr<SectionNode>> m_sectionStack;
                        ReporterPreferences m_reporterPrefs;
                                                   };

            template<char C>
            char const *getLineOfChars()
{
  static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
  if ( !*line )
    {
      std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
      line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
    }
  return line;
}

struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase>
{
  TestEventListenerBase( ReporterConfig const &_config );

  void assertionStarting(AssertionInfo const &) override;
  bool assertionEnded(AssertionStats const &) override;
};

                                                    } // end namespace Catch

// end catch_reporter_bases.hpp
// start catch_console_colour.h

namespace Catch
{

  struct Colour
  {
    enum Code
  {
    None = 0,

    White,
    Red,
    Green,
    Blue,
    Cyan,
    Yellow,
    Grey,

    Bright = 0x10,

    BrightRed = Bright | Red,
    BrightGreen = Bright | Green,
    LightGrey = Bright | Grey,
    BrightWhite = Bright | White,
    BrightYellow = Bright | Yellow,

    // By intention
    FileName = LightGrey,
    Warning = BrightYellow,
    ResultError = BrightRed,
    ResultSuccess = BrightGreen,
    ResultExpectedFailure = Warning,

    Error = BrightRed,
    Success = Green,

    OriginalExpression = Cyan,
    ReconstructedExpression = BrightYellow,

    SecondaryText = LightGrey,
    Headers = White
  };

  // Use constructed object for RAII guard
  Colour( Code _colourCode );
  Colour( Colour &&other ) noexcept;
  Colour &operator=( Colour&& other ) noexcept;
  ~Colour();

  // Use static method for one-shot changes
  static void use( Code _colourCode );

  private:
  bool m_moved = false;
  };

  std::ostream &operator << ( std::ostream &os, Colour const &);

} // end namespace Catch

// end catch_console_colour.h
// start catch_reporter_registrars.hpp


namespace Catch
{

  template<typename T>
  class ReporterRegistrar
  {

    class ReporterFactory : public IReporterFactory
    {

      virtual IStreamingReporterPtr create( ReporterConfig const &config ) const override
{
  return std::unique_ptr<T>( new T( config ) );
}

virtual std::string getDescription() const override
{
  return T::getDescription();
}
                      };

public:

explicit ReporterRegistrar( std::string const &name )
{
  getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() );
}
                                        };

template<typename T>
class ListenerRegistrar
{

  class ListenerFactory : public IReporterFactory
  {

    virtual IStreamingReporterPtr create( ReporterConfig const &config ) const override
{
  return std::unique_ptr<T>( new T( config ) );
}
virtual std::string getDescription() const override
{
  return std::string();
}
                      };

public:

ListenerRegistrar()
{
  getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() );
}
                                        };
  }

#if !defined(CATCH_CONFIG_DISABLE)

#define CATCH_REGISTER_REPORTER( name, reporterType ) \
  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS          \
  namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
  CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS

#define CATCH_REGISTER_LISTENER( listenerType ) \
  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS   \
  namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
  CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
#else // CATCH_CONFIG_DISABLE

#define CATCH_REGISTER_REPORTER(name, reporterType)
#define CATCH_REGISTER_LISTENER(listenerType)

#endif // CATCH_CONFIG_DISABLE

// end catch_reporter_registrars.hpp
// Allow users to base their work off existing reporters
// start catch_reporter_compact.h

namespace Catch
{

  struct CompactReporter : StreamingReporterBase<CompactReporter>
  {

    using StreamingReporterBase::StreamingReporterBase;

    ~CompactReporter() override;

    static std::string getDescription();

    ReporterPreferences getPreferences() const override;

    void noMatchingTestCases(std::string const &spec) override;

    void assertionStarting(AssertionInfo const &) override;

    bool assertionEnded(AssertionStats const &_assertionStats) override;

    void sectionEnded(SectionStats const &_sectionStats) override;

    void testRunEnded(TestRunStats const &_testRunStats) override;

  };

                                                } // end namespace Catch

// end catch_reporter_compact.h
// start catch_reporter_console.h

#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
// Note that 4062 (not all labels are handled
// and default is missing) is enabled
#endif

namespace Catch
{
  // Fwd decls
  struct SummaryColumn;
  class TablePrinter;

struct ConsoleReporter : StreamingReporterBase<ConsoleReporter>
  {
    std::unique_ptr<TablePrinter> m_tablePrinter;

    ConsoleReporter(ReporterConfig const &config);
    ~ConsoleReporter() override;
    static std::string getDescription();

    void noMatchingTestCases(std::string const &spec) override;

    void assertionStarting(AssertionInfo const &) override;

    bool assertionEnded(AssertionStats const &_assertionStats) override;

    void sectionStarting(SectionInfo const &_sectionInfo) override;
    void sectionEnded(SectionStats const &_sectionStats) override;

    void benchmarkStarting(BenchmarkInfo const &info) override;
    void benchmarkEnded(BenchmarkStats const &stats) override;

    void testCaseEnded(TestCaseStats const &_testCaseStats) override;
    void testGroupEnded(TestGroupStats const &_testGroupStats) override;
    void testRunEnded(TestRunStats const &_testRunStats) override;

    private:

    void lazyPrint();

    void lazyPrintWithoutClosingBenchmarkTable();
    void lazyPrintRunInfo();
    void lazyPrintGroupInfo();
    void printTestCaseAndSectionHeader();

    void printClosedHeader(std::string const &_name);
    void printOpenHeader(std::string const &_name);

    // if string has a : in first line will set indent to follow it on
    // subsequent lines
    void printHeaderString(std::string const &_string, std::size_t indent = 0);

    void printTotals(Totals const &totals);
    void printSummaryRow(std::string const &label, std::vector<SummaryColumn> const &cols, std::size_t row);

    void printTotalsDivider(Totals const &totals);
    void printSummaryDivider();

    private:
    bool m_headerPrinted = false;
                        };

} // end namespace Catch

#if defined(_MSC_VER)
#pragma warning(pop)
#endif

// end catch_reporter_console.h
// start catch_reporter_junit.h

// start catch_xmlwriter.h

#include <vector>

namespace Catch
{

  class XmlEncode
  {
    public:
    enum ForWhat { ForTextNodes, ForAttributes };

    XmlEncode( std::string const &str, ForWhat forWhat = ForTextNodes );

    void encodeTo( std::ostream &os ) const;

    friend std::ostream &operator << ( std::ostream &os, XmlEncode const &xmlEncode );

                                   private:
                                   std::string m_str;
                                   ForWhat m_forWhat;
                                  };

    class XmlWriter
    {
      public:

      class ScopedElement
      {
        public:
        ScopedElement( XmlWriter *writer );

        ScopedElement( ScopedElement&& other ) noexcept;
        ScopedElement &operator=( ScopedElement&& other ) noexcept;

        ~ScopedElement();

        ScopedElement &writeText( std::string const &text, bool indent = true );

        template<typename T>
        ScopedElement &writeAttribute( std::string const &name, T const &attribute )
{
  m_writer->writeAttribute( name, attribute );
  return *this;
}

private:
mutable XmlWriter *m_writer = nullptr;
                };

XmlWriter( std::ostream &os = Catch::cout() );
~XmlWriter();

XmlWriter( XmlWriter const &) = delete;
XmlWriter &operator=( XmlWriter const &) = delete;

XmlWriter &startElement( std::string const &name );

ScopedElement scopedElement( std::string const &name );

XmlWriter &endElement();

XmlWriter &writeAttribute( std::string const &name, std::string const &attribute );

XmlWriter &writeAttribute( std::string const &name, bool attribute );

template<typename T>
XmlWriter &writeAttribute( std::string const &name, T const &attribute )
{
  ReusableStringStream rss;
  rss << attribute;
  return writeAttribute( name, rss.str() );
}

XmlWriter &writeText( std::string const &text, bool indent = true );

XmlWriter &writeComment( std::string const &text );

void writeStylesheetRef( std::string const &url );

XmlWriter &writeBlankLine();

void ensureTagClosed();

private:

void writeDeclaration();

void newlineIfNecessary();

bool m_tagIsOpen = false;
bool m_needsNewline = false;
std::vector<std::string> m_tags;
std::string m_indent;
std::ostream &m_os;
           };

    }

// end catch_xmlwriter.h
namespace Catch
{

  class JunitReporter : public CumulativeReporterBase<JunitReporter>
  {
    public:
    JunitReporter(ReporterConfig const &_config);

    ~JunitReporter() override;

    static std::string getDescription();

    void noMatchingTestCases(std::string const & /*spec*/) override;

    void testRunStarting(TestRunInfo const &runInfo) override;

    void testGroupStarting(GroupInfo const &groupInfo) override;

    void testCaseStarting(TestCaseInfo const &testCaseInfo) override;
    bool assertionEnded(AssertionStats const &assertionStats) override;

    void testCaseEnded(TestCaseStats const &testCaseStats) override;

    void testGroupEnded(TestGroupStats const &testGroupStats) override;

    void testRunEndedCumulative() override;

    void writeGroup(TestGroupNode const &groupNode, double suiteTime);

    void writeTestCase(TestCaseNode const &testCaseNode);

    void writeSection(std::string const &className,
                      std::string const &rootName,
                      SectionNode const &sectionNode);

    void writeAssertions(SectionNode const &sectionNode);
    void writeAssertion(AssertionStats const &stats);

    XmlWriter xml;
    Timer suiteTimer;
    std::string stdOutForSuite;
    std::string stdErrForSuite;
    unsigned int unexpectedExceptions = 0;
    bool m_okToFail = false;
  };

                                                     } // end namespace Catch

// end catch_reporter_junit.h
// start catch_reporter_xml.h

namespace Catch
{
  class XmlReporter : public StreamingReporterBase<XmlReporter>
  {
    public:
    XmlReporter(ReporterConfig const &_config);

    ~XmlReporter() override;

    static std::string getDescription();

    virtual std::string getStylesheetRef() const;

    void writeSourceInfo(SourceLineInfo const &sourceInfo);

    public: // StreamingReporterBase

    void noMatchingTestCases(std::string const &s) override;

    void testRunStarting(TestRunInfo const &testInfo) override;

    void testGroupStarting(GroupInfo const &groupInfo) override;

    void testCaseStarting(TestCaseInfo const &testInfo) override;

    void sectionStarting(SectionInfo const &sectionInfo) override;

    void assertionStarting(AssertionInfo const &) override;

    bool assertionEnded(AssertionStats const &assertionStats) override;

    void sectionEnded(SectionStats const &sectionStats) override;

    void testCaseEnded(TestCaseStats const &testCaseStats) override;

    void testGroupEnded(TestGroupStats const &testGroupStats) override;

    void testRunEnded(TestRunStats const &testRunStats) override;

    private:
    Timer m_testCaseTimer;
    XmlWriter m_xml;
    int m_sectionDepth = 0;
  };

                                                  } // end namespace Catch

// end catch_reporter_xml.h

// end catch_external_interfaces.h
#endif

#endif // ! CATCH_CONFIG_IMPL_ONLY

#ifdef CATCH_IMPL
// start catch_impl.hpp

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wweak-vtables"
#endif

// Keep these here for external reporters
// start catch_test_case_tracker.h

#include <string>
#include <vector>
#include <memory>

namespace Catch
{
  namespace TestCaseTracking
  {

    struct NameAndLocation
    {
      std::string name;
      SourceLineInfo location;

      NameAndLocation( std::string const &_name, SourceLineInfo const &_location );
    };

    struct ITracker;

    using ITrackerPtr = std::shared_ptr<ITracker>;

    struct ITracker
    {
      virtual ~ITracker();

      // static queries
      virtual NameAndLocation const &nameAndLocation() const = 0;

      // dynamic queries
      virtual bool isComplete() const = 0; // Successfully completed or failed
      virtual bool isSuccessfullyCompleted() const = 0;
      virtual bool isOpen() const = 0; // Started but not complete
      virtual bool hasChildren() const = 0;

      virtual ITracker &parent() = 0;

      // actions
      virtual void close() = 0; // Successfully complete
      virtual void fail() = 0;
      virtual void markAsNeedingAnotherRun() = 0;

      virtual void addChild( ITrackerPtr const &child ) = 0;
      virtual ITrackerPtr findChild( NameAndLocation const &nameAndLocation ) = 0;
      virtual void openChild() = 0;

      // Debug/ checking
      virtual bool isSectionTracker() const = 0;
      virtual bool isIndexTracker() const = 0;
    };

    class TrackerContext
    {

      enum RunState
{
  NotStarted,
  Executing,
  CompletedCycle
};

ITrackerPtr m_rootTracker;
ITracker *m_currentTracker = nullptr;
RunState m_runState = NotStarted;

public:

static TrackerContext &instance();

ITracker &startRun();
void endRun();

void startCycle();
void completeCycle();

bool completedCycle() const;
ITracker &currentTracker();
void setCurrentTracker( ITracker *tracker );
    };

class TrackerBase : public ITracker
{
  protected:
  enum CycleState
{
  NotStarted,
  Executing,
  ExecutingChildren,
  NeedsAnotherRun,
  CompletedSuccessfully,
  Failed
};

class TrackerHasName
{
  NameAndLocation m_nameAndLocation;
  public:
  TrackerHasName( NameAndLocation const &nameAndLocation );
  bool operator ()( ITrackerPtr const &tracker ) const;
};

using Children = std::vector<ITrackerPtr>;
NameAndLocation m_nameAndLocation;
TrackerContext &m_ctx;
ITracker *m_parent;
Children m_children;
CycleState m_runState = NotStarted;

public:
TrackerBase( NameAndLocation const &nameAndLocation, TrackerContext &ctx, ITracker *parent );

NameAndLocation const &nameAndLocation() const override;
bool isComplete() const override;
bool isSuccessfullyCompleted() const override;
bool isOpen() const override;
bool hasChildren() const override;

void addChild( ITrackerPtr const &child ) override;

ITrackerPtr findChild( NameAndLocation const &nameAndLocation ) override;
ITracker &parent() override;

void openChild() override;

bool isSectionTracker() const override;
bool isIndexTracker() const override;

void open();

void close() override;
void fail() override;
void markAsNeedingAnotherRun() override;

private:
void moveToParent();
void moveToThis();
                            };

class SectionTracker : public TrackerBase
{
  std::vector<std::string> m_filters;
  public:
  SectionTracker( NameAndLocation const &nameAndLocation, TrackerContext &ctx, ITracker *parent );

  bool isSectionTracker() const override;

  static SectionTracker &acquire( TrackerContext &ctx, NameAndLocation const &nameAndLocation );

  void tryOpen();

  void addInitialFilters( std::vector<std::string> const &filters );
  void addNextFilters( std::vector<std::string> const &filters );
                     };

class IndexTracker : public TrackerBase
{
  int m_size;
  int m_index = -1;
  public:
  IndexTracker( NameAndLocation const &nameAndLocation, TrackerContext &ctx, ITracker *parent, int size );

  bool isIndexTracker() const override;
  void close() override;

  static IndexTracker &acquire( TrackerContext &ctx, NameAndLocation const &nameAndLocation, int size );

  int index() const;

  void moveNext();
};

                        } // namespace TestCaseTracking

using TestCaseTracking::ITracker;
using TestCaseTracking::TrackerContext;
using TestCaseTracking::SectionTracker;
using TestCaseTracking::IndexTracker;

             } // namespace Catch

// end catch_test_case_tracker.h

// start catch_leak_detector.h

namespace Catch
{

  struct LeakDetector
  {
    LeakDetector();
  };

}
// end catch_leak_detector.h
// Cpp files will be included in the single-header file here
// start catch_approx.cpp

#include <cmath>
#include <limits>

namespace
{

// Performs equivalent check of std::fabs(lhs - rhs) <= margin
// But without the subtraction to allow for INFINITY in comparison
  bool marginComparison(double lhs, double rhs, double margin)
{
  return (lhs + margin >= rhs) && (rhs + margin >= lhs);
}

}

namespace Catch
{
  namespace Detail
  {

    Approx::Approx ( double value )
    :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
    m_margin( 0.0 ),
    m_scale( 0.0 ),
    m_value( value )
{}

Approx Approx::custom()
{
  return Approx( 0 );
}

std::string Approx::toString() const
{
  ReusableStringStream rss;
  rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
                     return rss.str();
}

                   bool Approx::equalityComparisonImpl(const double other) const
{
  // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
  // Thanks to Richard Harris for his help refining the scaled margin value
  return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
}

                                                           } // end namespace Detail

std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const &value)
{
  return value.toString();
}

                       } // end namespace Catch
// end catch_approx.cpp
// start catch_assertionhandler.cpp

// start catch_context.h

#include <memory>

namespace Catch
{

  struct IResultCapture;
  struct IRunner;
  struct IConfig;
  struct IMutableContext;

  using IConfigPtr = std::shared_ptr<IConfig const>;

  struct IContext
{
  virtual ~IContext();

  virtual IResultCapture *getResultCapture() = 0;
  virtual IRunner *getRunner() = 0;
  virtual IConfigPtr const &getConfig() const = 0;
};

struct IMutableContext : IContext
{
  virtual ~IMutableContext();
  virtual void setResultCapture( IResultCapture *resultCapture ) = 0;
  virtual void setRunner( IRunner *runner ) = 0;
  virtual void setConfig( IConfigPtr const &config ) = 0;

  private:
  static IMutableContext *currentContext;
  friend IMutableContext &getCurrentMutableContext();
  friend void cleanUpContext();
  static void createContext();
};

inline IMutableContext &getCurrentMutableContext()
{
  if ( !IMutableContext::currentContext )
    IMutableContext::createContext();
  return *IMutableContext::currentContext;
}

inline IContext &getCurrentContext()
{
  return getCurrentMutableContext();
}

void cleanUpContext();
                                    }

// end catch_context.h
// start catch_debugger.h

namespace Catch
{
  bool isDebuggerActive();
}

#ifdef CATCH_PLATFORM_MAC

#define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */

#elif defined(CATCH_PLATFORM_LINUX)
// If we can use inline assembler, do it because this allows us to break
// directly at the location of the failing check instead of breaking inside
// raise() called from it, i.e. one stack frame below.
#if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
#define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */
#else // Fall back to the generic way.
#include <signal.h>

#define CATCH_TRAP() raise(SIGTRAP)
#endif
#elif defined(_MSC_VER)
#define CATCH_TRAP() __debugbreak()
#elif defined(__MINGW32__)
extern "C" __declspec(dllimport) void __stdcall DebugBreak();
#define CATCH_TRAP() DebugBreak()
#endif

#ifdef CATCH_TRAP
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
#else
namespace Catch
{
inline void doNothing() {}
}
#define CATCH_BREAK_INTO_DEBUGGER() Catch::doNothing()
#endif

// end catch_debugger.h
// start catch_run_context.h

// start catch_fatal_condition.h

// start catch_windows_h_proxy.h


#if defined(CATCH_PLATFORM_WINDOWS)

#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
#  define CATCH_DEFINED_NOMINMAX
#  define NOMINMAX
#endif
#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
#  define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
#  define WIN32_LEAN_AND_MEAN
#endif

#ifdef __AFXDLL
#include <AfxWin.h>
#else
#include <windows.h>
#endif

#ifdef CATCH_DEFINED_NOMINMAX
#  undef NOMINMAX
#endif
#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
#  undef WIN32_LEAN_AND_MEAN
#endif

#endif // defined(CATCH_PLATFORM_WINDOWS)

// end catch_windows_h_proxy.h
#if defined( CATCH_CONFIG_WINDOWS_SEH )

namespace Catch
{

  struct FatalConditionHandler
  {

    static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
    FatalConditionHandler();
    static void reset();
    ~FatalConditionHandler();

    private:
    static bool isSet;
    static ULONG guaranteeSize;
    static PVOID exceptionHandlerHandle;
  };

} // namespace Catch

#elif defined ( CATCH_CONFIG_POSIX_SIGNALS )

#include <signal.h>

namespace Catch
{

  struct FatalConditionHandler
  {

    static bool isSet;
    static struct sigaction oldSigActions[];
    static stack_t oldSigStack;
    static char altStackMem[];

    static void handleSignal( int sig );

    FatalConditionHandler();
    ~FatalConditionHandler();
    static void reset();
  };

} // namespace Catch

#else

namespace Catch
{
  struct FatalConditionHandler
  {
    void reset();
  };
}

#endif

// end catch_fatal_condition.h
#include <string>

namespace Catch
{

  struct IMutableContext;

  ///////////////////////////////////////////////////////////////////////////

  class RunContext : public IResultCapture, public IRunner
  {

    public:
    RunContext( RunContext const &) = delete;
    RunContext &operator =( RunContext const &) = delete;

    explicit RunContext( IConfigPtr const &_config, IStreamingReporterPtr &&reporter );

    ~RunContext() override;

    void testGroupStarting( std::string const &testSpec, std::size_t groupIndex, std::size_t groupsCount );
    void testGroupEnded( std::string const &testSpec, Totals const &totals, std::size_t groupIndex, std::size_t groupsCount );

    Totals runTest(TestCase const &testCase);

    IConfigPtr config() const;
    IStreamingReporter &reporter() const;

    public: // IResultCapture

    // Assertion handlers
    void handleExpr
    (   AssertionInfo const &info,
        ITransientExpression const &expr,
        AssertionReaction &reaction ) override;
    void handleMessage
    (   AssertionInfo const &info,
        ResultWas::OfType resultType,
        StringRef const &message,
        AssertionReaction &reaction ) override;
    void handleUnexpectedExceptionNotThrown
    (   AssertionInfo const &info,
        AssertionReaction &reaction ) override;
    void handleUnexpectedInflightException
    (   AssertionInfo const &info,
        std::string const &message,
        AssertionReaction &reaction ) override;
    void handleIncomplete
    (   AssertionInfo const &info ) override;
    void handleNonExpr
    (   AssertionInfo const &info,
        ResultWas::OfType resultType,
        AssertionReaction &reaction ) override;

    bool sectionStarted( SectionInfo const &sectionInfo, Counts &assertions ) override;

    void sectionEnded( SectionEndInfo const &endInfo ) override;
    void sectionEndedEarly( SectionEndInfo const &endInfo ) override;

    void benchmarkStarting( BenchmarkInfo const &info ) override;
    void benchmarkEnded( BenchmarkStats const &stats ) override;

    void pushScopedMessage( MessageInfo const &message ) override;
    void popScopedMessage( MessageInfo const &message ) override;

    std::string getCurrentTestName() const override;

    const AssertionResult *getLastResult() const override;

    void exceptionEarlyReported() override;

    void handleFatalErrorCondition( StringRef message ) override;

    bool lastAssertionPassed() override;

    void assertionPassed() override;

    public:
    // !TBD We need to do this another way!
    bool aborting() const final;

    private:

    void runCurrentTest( std::string &redirectedCout, std::string &redirectedCerr );
    void invokeActiveTestCase();

    void resetAssertionInfo();
    bool testForMissingAssertions( Counts &assertions );

    void assertionEnded( AssertionResult const &result );
    void reportExpr
    (   AssertionInfo const &info,
        ResultWas::OfType resultType,
        ITransientExpression const *expr,
        bool negated );

    void populateReaction( AssertionReaction &reaction );

    private:

    void handleUnfinishedSections();

    TestRunInfo m_runInfo;
    IMutableContext &m_context;
    TestCase const *m_activeTestCase = nullptr;
    ITracker *m_testCaseTracker;
    Option<AssertionResult> m_lastResult;

    IConfigPtr m_config;
    Totals m_totals;
    IStreamingReporterPtr m_reporter;
    std::vector<MessageInfo> m_messages;
    AssertionInfo m_lastAssertionInfo;
    std::vector<SectionEndInfo> m_unfinishedSections;
    std::vector<ITracker *> m_activeSections;
    TrackerContext m_trackerContext;
    bool m_lastAssertionPassed = false;
    bool m_shouldReportUnexpected = true;
    bool m_includeSuccessfulResults;
               };

               } // end namespace Catch

// end catch_run_context.h
namespace Catch
{

  auto operator <<( std::ostream &os, ITransientExpression const &expr ) -> std::ostream &
{
  expr.streamReconstructedExpression( os );
  return os;
}

LazyExpression::LazyExpression( bool isNegated )
:   m_isNegated( isNegated )
{}

LazyExpression::LazyExpression( LazyExpression const &other ) : m_isNegated( other.m_isNegated ) {}

LazyExpression::operator bool() const
{
  return m_transientExpression != nullptr;
}

auto operator << ( std::ostream &os, LazyExpression const &lazyExpr ) -> std::ostream &
{
  if ( lazyExpr.m_isNegated )
    os << "!";

  if ( lazyExpr )
    {
      if ( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )
        os << "(" << *lazyExpr.m_transientExpression << ")";
      else
        os << *lazyExpr.m_transientExpression;
    }
  else {
      os << "{** error - unchecked empty expression requested **}";
    }
  return os;
}

AssertionHandler::AssertionHandler
(   StringRef macroName,
    SourceLineInfo const &lineInfo,
    StringRef capturedExpression,
    ResultDisposition::Flags resultDisposition )
:   m_assertionInfo { macroName, lineInfo, capturedExpression, resultDisposition },
m_resultCapture( getResultCapture() )
{}

void AssertionHandler::handleExpr( ITransientExpression const &expr )
{
  m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
}
void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const &message)
{
  m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );
}

auto AssertionHandler::allowThrows() const -> bool
{
  return getCurrentContext().getConfig()->allowThrows();
}

void AssertionHandler::complete()
{
  setCompleted();
  if ( m_reaction.shouldDebugBreak )
    {

      // If you find your debugger stopping you here then go one level up on the
      // call-stack for the code that caused it (typically a failed assertion)

      // (To go back to the test and change execution, jump over the throw, next)
      CATCH_BREAK_INTO_DEBUGGER();
    }
  if ( m_reaction.shouldThrow )
    throw Catch::TestFailureException();
}
void AssertionHandler::setCompleted()
{
  m_completed = true;
}

void AssertionHandler::handleUnexpectedInflightException()
{
  m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
}

void AssertionHandler::handleExceptionThrownAsExpected()
{
  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
}
void AssertionHandler::handleExceptionNotThrownAsExpected()
{
  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
}

void AssertionHandler::handleUnexpectedExceptionNotThrown()
{
  m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );
}

void AssertionHandler::handleThrowingCallSkipped()
{
  m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);
}

// This is the overload that takes a string and infers the Equals matcher from it
// The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
void handleExceptionMatchExpr( AssertionHandler &handler, std::string const &str, StringRef matcherString  )
{
  handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
}

   } // namespace Catch
// end catch_assertionhandler.cpp
// start catch_assertionresult.cpp

namespace Catch
{
  AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const &_lazyExpression):
  lazyExpression(_lazyExpression),
resultType(_resultType) {}

std::string AssertionResultData::reconstructExpression() const
{

  if ( reconstructedExpression.empty() )
    {
      if ( lazyExpression )
        {
          ReusableStringStream rss;
          rss << lazyExpression;
          reconstructedExpression = rss.str();
        }
    }
  return reconstructedExpression;
}

AssertionResult::AssertionResult( AssertionInfo const &info, AssertionResultData const &data )
:   m_info( info ),
m_resultData( data )
{}

// Result was a success
bool AssertionResult::succeeded() const
{
  return Catch::isOk( m_resultData.resultType );
}

// Result was a success, or failure is suppressed
bool AssertionResult::isOk() const
{
  return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
}

ResultWas::OfType AssertionResult::getResultType() const
{
  return m_resultData.resultType;
}

bool AssertionResult::hasExpression() const
{
  return m_info.capturedExpression[0] != 0;
}

bool AssertionResult::hasMessage() const
{
  return !m_resultData.message.empty();
}

std::string AssertionResult::getExpression() const
{
  if ( isFalseTest( m_info.resultDisposition ) )
    return "!(" + m_info.capturedExpression + ")";
  else
    return m_info.capturedExpression;
}

std::string AssertionResult::getExpressionInMacro() const
{
  std::string expr;
  if ( m_info.macroName[0] == 0 )
    expr = m_info.capturedExpression;
  else
    {
      expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
      expr += m_info.macroName;
      expr += "( ";
      expr += m_info.capturedExpression;
      expr += " )";
    }
  return expr;
}

bool AssertionResult::hasExpandedExpression() const
{
  return hasExpression() && getExpandedExpression() != getExpression();
}

std::string AssertionResult::getExpandedExpression() const
{
  std::string expr = m_resultData.reconstructExpression();
  return expr.empty()
  ? getExpression()
  : expr;
}

std::string AssertionResult::getMessage() const
{
  return m_resultData.message;
}
SourceLineInfo AssertionResult::getSourceInfo() const
{
  return m_info.lineInfo;
}

StringRef AssertionResult::getTestMacroName() const
{
  return m_info.macroName;
}

    } // end namespace Catch
// end catch_assertionresult.cpp
// start catch_benchmark.cpp

namespace Catch
{

  auto BenchmarkLooper::getResolution() -> uint64_t
{
  return getEstimatedClockResolution() * getCurrentContext().getConfig()->benchmarkResolutionMultiple();
}

void BenchmarkLooper::reportStart()
{
  getResultCapture().benchmarkStarting( { m_name } );
}
auto BenchmarkLooper::needsMoreIterations() -> bool
{
  auto elapsed = m_timer.getElapsedNanoseconds();

  // Exponentially increasing iterations until we're confident in our timer resolution
  if ( elapsed < m_resolution )
    {
      m_iterationsToRun *= 10;
      return true;
    }

  getResultCapture().benchmarkEnded( { { m_name }, m_count, elapsed } );
  return false;
}

   } // end namespace Catch
// end catch_benchmark.cpp
// start catch_capture_matchers.cpp

namespace Catch
{

  using StringMatcher = Matchers::Impl::MatcherBase<std::string>;

  // This is the general overload that takes a any string matcher
  // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
  // the Equals matcher (so the header does not mention matchers)
  void handleExceptionMatchExpr( AssertionHandler &handler, StringMatcher const &matcher, StringRef matcherString  )
{
  std::string exceptionMessage = Catch::translateActiveException();
  MatchExpr<std::string, StringMatcher const &> expr( exceptionMessage, matcher, matcherString );
  handler.handleExpr( expr );
}

         } // namespace Catch
// end catch_capture_matchers.cpp
// start catch_commandline.cpp

// start catch_commandline.h

// start catch_clara.h

// Use Catch's value for console width (store Clara's off to the side, if present)
#ifdef CLARA_CONFIG_CONSOLE_WIDTH
#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
#undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
#endif
#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wweak-vtables"
#pragma clang diagnostic ignored "-Wexit-time-destructors"
#pragma clang diagnostic ignored "-Wshadow"
#endif

// start clara.hpp
// Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See https://github.com/philsquared/Clara for more details

// Clara v1.1.4


#ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH
#define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80
#endif

#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH
#endif

#ifndef CLARA_CONFIG_OPTIONAL_TYPE
#ifdef __has_include
#if __has_include(<optional>) && __cplusplus >= 201703L
#include <optional>
#define CLARA_CONFIG_OPTIONAL_TYPE std::optional
#endif
#endif
#endif

// ----------- #included from clara_textflow.hpp -----------

// TextFlowCpp
//
// A single-header library for wrapping and laying out basic text, by Phil Nash
//
// This work is licensed under the BSD 2-Clause license.
// See the accompanying LICENSE file, or the one at https://opensource.org/licenses/BSD-2-Clause
//
// This project is hosted at https://github.com/philsquared/textflowcpp


#include <cassert>
#include <ostream>
#include <sstream>
#include <vector>

#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH
#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80
#endif

namespace Catch
{
  namespace clara
  {
    namespace TextFlow
    {

      inline auto isWhitespace( char c ) -> bool
{
  static std::string chars = " \t\n\r";
  return chars.find( c ) != std::string::npos;
}
inline auto isBreakableBefore( char c ) -> bool
{
  static std::string chars = "[({<|";
  return chars.find( c ) != std::string::npos;
}
inline auto isBreakableAfter( char c ) -> bool
{
  static std::string chars = "])}>.,:;*+-=&/\\";
  return chars.find( c ) != std::string::npos;
}

class Columns;

class Column
{
  std::vector<std::string> m_strings;
  size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;
  size_t m_indent = 0;
  size_t m_initialIndent = std::string::npos;

  public:
  class iterator
  {
    friend Column;

    Column const &m_column;
    size_t m_stringIndex = 0;
    size_t m_pos = 0;

    size_t m_len = 0;
    size_t m_end = 0;
    bool m_suffix = false;

    iterator( Column const &column, size_t stringIndex )
    :   m_column( column ),
    m_stringIndex( stringIndex )
{}

auto line() const -> std::string const &
{
  return m_column.m_strings[m_stringIndex];
}

auto isBoundary( size_t at ) const -> bool
{
  assert( at > 0 );
  assert( at <= line().size() );

  return at == line().size() ||
  ( isWhitespace( line()[at] ) && !isWhitespace( line()[at-1] ) ) ||
  isBreakableBefore( line()[at] ) ||
  isBreakableAfter( line()[at-1] );
}

void calcLength()
{
  assert( m_stringIndex < m_column.m_strings.size() );

  m_suffix = false;
  auto width = m_column.m_width-indent();
  m_end = m_pos;
  while ( m_end < line().size() && line()[m_end] != '\n' )
            ++m_end;

  if ( m_end < m_pos + width )
    {
      m_len = m_end - m_pos;
    }
  else
    {
      size_t len = width;
      while (len > 0 && !isBoundary(m_pos + len))
        --len;
      while (len > 0 && isWhitespace( line()[m_pos + len - 1] ))
        --len;

      if (len > 0)
        {
          m_len = len;
        }
      else
        {
          m_suffix = true;
          m_len = width - 1;
        }
    }
}

auto indent() const -> size_t
{
  auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;
  return initial == std::string::npos ? m_column.m_indent : initial;
}

auto addIndentAndSuffix(std::string const &plain) const -> std::string
{
  return std::string( indent(), ' ' ) + (m_suffix ? plain + "-" : plain);
}

public:
explicit iterator( Column const &column ) : m_column( column )
{
  assert( m_column.m_width > m_column.m_indent );
  assert( m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent );
  calcLength();
  if ( m_len == 0 )
    m_stringIndex++; // Empty string
}

auto operator *() const -> std::string
{
  assert( m_stringIndex < m_column.m_strings.size() );
  assert( m_pos <= m_end );
  if ( m_pos + m_column.m_width < m_end )
         return addIndentAndSuffix(line().substr(m_pos, m_len));
  else
    return addIndentAndSuffix(line().substr(m_pos, m_end - m_pos));
}

auto operator ++() -> iterator &
{
  m_pos += m_len;
  if ( m_pos < line().size() && line()[m_pos] == '\n' )
    m_pos += 1;
  else
    while ( m_pos < line().size() && isWhitespace( line()[m_pos] ) )
      ++m_pos;

  if ( m_pos == line().size() )
    {
      m_pos = 0;
      ++m_stringIndex;
    }
  if ( m_stringIndex < m_column.m_strings.size() )
    calcLength();
  return *this;
}
auto operator ++(int) -> iterator
{
  iterator prev( *this );
  operator++();
  return prev;
}

auto operator ==( iterator const &other ) const -> bool
{
  return
  m_pos == other.m_pos &&
  m_stringIndex == other.m_stringIndex &&
  &m_column == &other.m_column;
}
auto operator !=( iterator const &other ) const -> bool
{
  return !operator==( other );
}
   };
using const_iterator = iterator;

explicit Column( std::string const &text )
{
  m_strings.push_back( text );
}

auto width( size_t newWidth ) -> Column &
{
  assert( newWidth > 0 );
  m_width = newWidth;
  return *this;
}
auto indent( size_t newIndent ) -> Column &
{
  m_indent = newIndent;
  return *this;
}
auto initialIndent( size_t newIndent ) -> Column &
{
  m_initialIndent = newIndent;
  return *this;
}

auto width() const -> size_t
{
  return m_width;
}
auto begin() const -> iterator
{
  return iterator( *this );
}
auto end() const -> iterator
{
  return { *this, m_strings.size() };
}

inline friend std::ostream &operator << ( std::ostream &os, Column const &col )
{
  bool first = true;
  for ( auto line : col )
    {
      if ( first )
        first = false;
      else
        os << "\n";
      os <<  line;
    }
  return os;
}

auto operator + ( Column const &other ) -> Columns;

auto toString() const -> std::string
{
  std::ostringstream oss;
  oss << *this;
  return oss.str();
}
    };

class Spacer : public Column
{

  public:
  explicit Spacer( size_t spaceWidth ) : Column( "" )
{
  width( spaceWidth );
}
};

class Columns
{
  std::vector<Column> m_columns;

  public:

  class iterator
  {
    friend Columns;
    struct EndTag {};

    std::vector<Column> const &m_columns;
    std::vector<Column::iterator> m_iterators;
    size_t m_activeIterators;

    iterator( Columns const &columns, EndTag )
    :   m_columns( columns.m_columns ),
    m_activeIterators( 0 )
{
  m_iterators.reserve( m_columns.size() );

  for ( auto const &col : m_columns )
    m_iterators.push_back( col.end() );
}

public:
explicit iterator( Columns const &columns )
:   m_columns( columns.m_columns ),
m_activeIterators( m_columns.size() )
{
  m_iterators.reserve( m_columns.size() );

  for ( auto const &col : m_columns )
    m_iterators.push_back( col.begin() );
}

auto operator ==( iterator const &other ) const -> bool
{
  return m_iterators == other.m_iterators;
}
auto operator !=( iterator const &other ) const -> bool
{
  return m_iterators != other.m_iterators;
}
auto operator *() const -> std::string
{
  std::string row, padding;

  for ( size_t i = 0; i < m_columns.size(); ++i )
    {
      auto width = m_columns[i].width();
      if ( m_iterators[i] != m_columns[i].end() )
        {
          std::string col = *m_iterators[i];
          row += padding + col;
          if ( col.size() < width )
                 padding = std::string( width - col.size(), ' ' );
          else
            padding = "";
        }
      else
        {
          padding += std::string( width, ' ' );
        }
    }
  return row;
}
auto operator ++() -> iterator &
{
  for ( size_t i = 0; i < m_columns.size(); ++i )
    {
      if (m_iterators[i] != m_columns[i].end())
        ++m_iterators[i];
    }
  return *this;
}
auto operator ++(int) -> iterator
{
  iterator prev( *this );
  operator++();
  return prev;
}
    };
using const_iterator = iterator;

auto begin() const -> iterator
{
  return iterator( *this );
}
auto end() const -> iterator
{
  return { *this, iterator::EndTag() };
}

auto operator += ( Column const &col ) -> Columns &
{
  m_columns.push_back( col );
  return *this;
}
auto operator + ( Column const &col ) -> Columns
{
  Columns combined = *this;
  combined += col;
  return combined;
}

inline friend std::ostream &operator << ( std::ostream &os, Columns const &cols )
{

  bool first = true;
  for ( auto line : cols )
    {
      if ( first )
        first = false;
      else
        os << "\n";
      os << line;
    }
  return os;
}

auto toString() const -> std::string
{
  std::ostringstream oss;
  oss << *this;
  return oss.str();
}
    };

inline auto Column::operator + ( Column const &other ) -> Columns
{
  Columns cols;
  cols += *this;
  cols += other;
  return cols;
}
   }
   }
                                     } // namespace Catch::clara::TextFlow

// ----------- end of #include from clara_textflow.hpp -----------
// ........... back in clara.hpp

#include <memory>
#include <set>
#include <algorithm>

#if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )
#define CATCH_PLATFORM_WINDOWS
#endif

namespace Catch
{
  namespace clara
  {
    namespace detail
    {

      // Traits for extracting arg and return type of lambdas (for single argument lambdas)
      template<typename L>
      struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};

      template<typename ClassT, typename ReturnT, typename... Args>
      struct UnaryLambdaTraits<ReturnT( ClassT::*)( Args... ) const>
{
  static const bool isValid = false;
};

template<typename ClassT, typename ReturnT, typename ArgT>
struct UnaryLambdaTraits<ReturnT( ClassT::*)( ArgT ) const>
{
  static const bool isValid = true;
  using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;
  using ReturnType = ReturnT;
};

class TokenStream;

// Transport for raw args (copied from main args, or supplied via init list for testing)
class Args
{
  friend TokenStream;
  std::string m_exeName;
  std::vector<std::string> m_args;

  public:
  Args( int argc, char const *const *argv )
  : m_exeName(argv[0]),
m_args(argv + 1, argv + argc) {}

Args( std::initializer_list<std::string> args )
:   m_exeName( *args.begin() ),
m_args( args.begin()+1, args.end() )
{}

auto exeName() const -> std::string
{
  return m_exeName;
}
    };

// Wraps a token coming from a token stream. These may not directly correspond to strings as a single string
// may encode an option + its argument if the : or = form is used
enum class TokenType
{
  Option, Argument
};
struct Token
{
  TokenType type;
  std::string token;
};

inline auto isOptPrefix( char c ) -> bool
{
  return c == '-'
#ifdef CATCH_PLATFORM_WINDOWS
  || c == '/'
#endif
  ;
}

// Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
class TokenStream
{
  using Iterator = std::vector<std::string>::const_iterator;
  Iterator it;
  Iterator itEnd;
  std::vector<Token> m_tokenBuffer;

  void loadBuffer()
{
  m_tokenBuffer.resize( 0 );

  // Skip any empty strings
  while ( it != itEnd && it->empty() )
    ++it;

  if ( it != itEnd )
    {
      auto const &next = *it;
      if ( isOptPrefix( next[0] ) )
        {
          auto delimiterPos = next.find_first_of( " :=" );
          if ( delimiterPos != std::string::npos )
            {
              m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
              m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );
            }
          else
            {
              if ( next[1] != '-' && next.size() > 2 )
                {
                  std::string opt = "- ";
                  for ( size_t i = 1; i < next.size(); ++i )
                    {
                      opt[1] = next[i];
                      m_tokenBuffer.push_back( { TokenType::Option, opt } );
                    }
                }
              else
                {
                  m_tokenBuffer.push_back( { TokenType::Option, next } );
                }
            }
        }
      else
        {
          m_tokenBuffer.push_back( { TokenType::Argument, next } );
        }
    }
}

public:
explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}

TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd )
{
  loadBuffer();
}

explicit operator bool() const
{
  return !m_tokenBuffer.empty() || it != itEnd;
}

auto count() const -> size_t
{
  return m_tokenBuffer.size() + (itEnd - it);
}

auto operator*() const -> Token
{
  assert( !m_tokenBuffer.empty() );
  return m_tokenBuffer.front();
}

auto operator->() const -> Token const *
{
  assert( !m_tokenBuffer.empty() );
  return &m_tokenBuffer.front();
}

auto operator++() -> TokenStream &
{
  if ( m_tokenBuffer.size() >= 2 )
    {
      m_tokenBuffer.erase( m_tokenBuffer.begin() );
    }
  else {
      if ( it != itEnd )
        ++it;
      loadBuffer();
    }
  return *this;
}
    };

class ResultBase
{
  public:
  enum Type
{
  Ok, LogicError, RuntimeError
};

protected:
ResultBase( Type type ) : m_type( type ) {}
virtual ~ResultBase() = default;

virtual void enforceOk() const = 0;

Type m_type;
};

template<typename T>
class ResultValueBase : public ResultBase
{
  public:
  auto value() const -> T const &
{
  enforceOk();
  return m_value;
}

protected:
ResultValueBase( Type type ) : ResultBase( type ) {}

ResultValueBase( ResultValueBase const &other ) : ResultBase( other )
{
  if ( m_type == ResultBase::Ok )
    new( &m_value ) T( other.m_value );
}

ResultValueBase( Type, T const &value ) : ResultBase( Ok )
{
  new( &m_value ) T( value );
}

auto operator=( ResultValueBase const &other ) -> ResultValueBase &
{
  if ( m_type == ResultBase::Ok )
    m_value.~T();
  ResultBase::operator=(other);
  if ( m_type == ResultBase::Ok )
    new( &m_value ) T( other.m_value );
  return *this;
}

~ResultValueBase() override
{
  if ( m_type == Ok )
    m_value.~T();
}

union
{
  T m_value;
};
};

template<>
class ResultValueBase<void> : public ResultBase
{
  protected:
  using ResultBase::ResultBase;
};

template<typename T = void>
class BasicResult : public ResultValueBase<T>
{
  public:
  template<typename U>
  explicit BasicResult( BasicResult<U> const &other )
  :   ResultValueBase<T>( other.type() ),
  m_errorMessage( other.errorMessage() )
{
  assert( type() != ResultBase::Ok );
}

template<typename U>
static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }
static auto ok() -> BasicResult { return { ResultBase::Ok }; }
static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }
static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }

explicit operator bool() const
{
  return m_type == ResultBase::Ok;
}
auto type() const -> ResultBase::Type
{
  return m_type;
}
auto errorMessage() const -> std::string
{
  return m_errorMessage;
}

protected:
void enforceOk() const override
{

  // Errors shouldn't reach this point, but if they do
  // the actual error message will be in m_errorMessage
  assert( m_type != ResultBase::LogicError );
  assert( m_type != ResultBase::RuntimeError );
  if ( m_type != ResultBase::Ok )
    std::abort();
}

std::string m_errorMessage; // Only populated if resultType is an error

BasicResult( ResultBase::Type type, std::string const &message )
:   ResultValueBase<T>(type),
m_errorMessage(message)
{
  assert( m_type != ResultBase::Ok );
}

using ResultValueBase<T>::ResultValueBase;
using ResultBase::m_type;
                     };

enum class ParseResultType
{
  Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
};

class ParseState
{
  public:

  ParseState( ParseResultType type, TokenStream const &remainingTokens )
  : m_type(type),
  m_remainingTokens( remainingTokens )
{}

auto type() const -> ParseResultType
{
  return m_type;
}
auto remainingTokens() const -> TokenStream
{
  return m_remainingTokens;
}

private:
ParseResultType m_type;
TokenStream m_remainingTokens;
};

using Result = BasicResult<void>;
using ParserResult = BasicResult<ParseResultType>;
using InternalParseResult = BasicResult<ParseState>;

struct HelpColumns
{
  std::string left;
  std::string right;
};

template<typename T>
inline auto convertInto( std::string const &source, T &target ) -> ParserResult
{
  std::stringstream ss;
  ss << source;
  ss >> target;
  if ( ss.fail() )
    return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" );
  else
    return ParserResult::ok( ParseResultType::Matched );
}
inline auto convertInto( std::string const &source, std::string &target ) -> ParserResult
{
  target = source;
  return ParserResult::ok( ParseResultType::Matched );
}
inline auto convertInto( std::string const &source, bool &target ) -> ParserResult
{
  std::string srcLC = source;
  std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c )
  {
    return static_cast<char>( ::tolower(c) );
  } );
  if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
    target = true;
  else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
    target = false;
  else
    return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" );
  return ParserResult::ok( ParseResultType::Matched );
}
#ifdef CLARA_CONFIG_OPTIONAL_TYPE
template<typename T>
inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T> &target ) -> ParserResult
{
  T temp;
  auto result = convertInto( source, temp );
  if ( result )
    target = std::move(temp);
  return result;
}
#endif // CLARA_CONFIG_OPTIONAL_TYPE

struct NonCopyable
{
  NonCopyable() = default;
  NonCopyable( NonCopyable const &) = delete;
  NonCopyable( NonCopyable &&) = delete;
  NonCopyable &operator=( NonCopyable const &) = delete;
  NonCopyable &operator=( NonCopyable && ) = delete;
};

struct BoundRef : NonCopyable
{
  virtual ~BoundRef() = default;
  virtual auto isContainer() const -> bool
{
  return false;
}
virtual auto isFlag() const -> bool
{
  return false;
}
};
struct BoundValueRefBase : BoundRef
{
  virtual auto setValue( std::string const &arg ) -> ParserResult = 0;
};
struct BoundFlagRefBase : BoundRef
{
  virtual auto setFlag( bool flag ) -> ParserResult = 0;
  virtual auto isFlag() const -> bool
{
  return true;
}
};

template<typename T>
struct BoundValueRef : BoundValueRefBase
{
  T &m_ref;

explicit BoundValueRef( T &ref ) : m_ref( ref ) {}

auto setValue( std::string const &arg ) -> ParserResult override
{
  return convertInto( arg, m_ref );
}
};

template<typename T>
struct BoundValueRef<std::vector<T>> : BoundValueRefBase
{
  std::vector<T> &m_ref;

explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}

auto isContainer() const -> bool override
{
  return true;
}

auto setValue( std::string const &arg ) -> ParserResult override
{
  T temp;
  auto result = convertInto( arg, temp );
  if ( result )
    m_ref.push_back( temp );
  return result;
}
                        };

struct BoundFlagRef : BoundFlagRefBase
{
  bool &m_ref;

explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}

auto setFlag( bool flag ) -> ParserResult override
{
  m_ref = flag;
  return ParserResult::ok( ParseResultType::Matched );
}
};

template<typename ReturnType>
struct LambdaInvoker
{
  static_assert( std::is_same<ReturnType, ParserResult>::value, "Lambda must return void or clara::ParserResult" );

  template<typename L, typename ArgType>
  static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult
{
  return lambda( arg );
}
          };

template<>
struct LambdaInvoker<void>
{
  template<typename L, typename ArgType>
  static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult
{
  lambda( arg );
  return ParserResult::ok( ParseResultType::Matched );
}
          };

template<typename ArgType, typename L>
inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult
{
  ArgType temp{};
  auto result = convertInto( arg, temp );
  return !result
  ? result
  : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );
}

template<typename L>
struct BoundLambda : BoundValueRefBase
{
  L m_lambda;

  static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}

auto setValue( std::string const &arg ) -> ParserResult override
{
  return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );
}
                                              };

template<typename L>
struct BoundFlagLambda : BoundFlagRefBase
{
  L m_lambda;

  static_assert( UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument" );
  static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, "flags must be boolean" );

explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}

auto setFlag( bool flag ) -> ParserResult override
{
  return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );
}
                                               };

enum class Optionality
{
  Optional, Required
};

struct Parser;

class ParserBase
{
  public:
  virtual ~ParserBase() = default;
  virtual auto validate() const -> Result
{
  return Result::ok();
}
virtual auto parse( std::string const &exeName, TokenStream const &tokens) const -> InternalParseResult  = 0;
virtual auto cardinality() const -> size_t
{
  return 1;
}

auto parse( Args const &args ) const -> InternalParseResult
{
  return parse( args.exeName(), TokenStream( args ) );
}
};

template<typename DerivedT>
class ComposableParserImpl : public ParserBase
{
  public:
  template<typename T>
  auto operator|( T const &other ) const -> Parser;

  template<typename T>
  auto operator+( T const &other ) const -> Parser;
          };

// Common code and state for Args and Opts
template<typename DerivedT>
class ParserRefImpl : public ComposableParserImpl<DerivedT>
{
protected:
  Optionality m_optionality = Optionality::Optional;
  std::shared_ptr<BoundRef> m_ref;
  std::string m_hint;
  std::string m_description;

  explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}

public:
  template<typename T>
  ParserRefImpl( T &ref, std::string const &hint )
    :   m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),
        m_hint( hint )
  {}

  template<typename LambdaT>
  ParserRefImpl( LambdaT const &ref, std::string const &hint )
    :   m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),
        m_hint(hint)
  {}

  auto operator()( std::string const &description ) -> DerivedT &
  {
    m_description = description;
    return static_cast<DerivedT &>( *this );
  }

  auto optional() -> DerivedT &
  {
    m_optionality = Optionality::Optional;
    return static_cast<DerivedT &>( *this );
  };

  auto required() -> DerivedT &
  {
    m_optionality = Optionality::Required;
    return static_cast<DerivedT &>( *this );
  };

  auto isOptional() const -> bool
  {
    return m_optionality == Optionality::Optional;
  }

  auto cardinality() const -> size_t override
  {
    if ( m_ref->isContainer() )
      return 0;
    else
      return 1;
  }

  auto hint() const -> std::string
  {
    return m_hint;
  }
};

class ExeName : public ComposableParserImpl<ExeName>
{
  std::shared_ptr<std::string> m_name;
  std::shared_ptr<BoundValueRefBase> m_ref;

  template<typename LambdaT>
  static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase>
{
  return std::make_shared<BoundLambda<LambdaT>>( lambda) ;
}

public:
ExeName() : m_name( std::make_shared<std::string>( "<executable>" ) ) {}

explicit ExeName( std::string &ref ) : ExeName()
{
  m_ref = std::make_shared<BoundValueRef<std::string>>( ref );
}

template<typename LambdaT>
explicit ExeName( LambdaT const &lambda ) : ExeName()
{
  m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda );
}

// The exe name is not parsed out of the normal tokens, but is handled specially
auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override
{
  return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
}

auto name() const -> std::string
{
  return *m_name;
}
auto set( std::string const &newName ) -> ParserResult
{

  auto lastSlash = newName.find_last_of( "\\/" );
  auto filename = ( lastSlash == std::string::npos )
  ? newName
  : newName.substr( lastSlash+1 );

  *m_name = filename;
  if ( m_ref )
    return m_ref->setValue( filename );
  else
    return ParserResult::ok( ParseResultType::Matched );
}
                                    };

class Arg : public ParserRefImpl<Arg>
{
  public:
  using ParserRefImpl::ParserRefImpl;

  auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override
{
  auto validationResult = validate();
  if ( !validationResult )
    return InternalParseResult( validationResult );

  auto remainingTokens = tokens;
  auto const &token = *remainingTokens;
  if ( token.type != TokenType::Argument )
    return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );

  assert( !m_ref->isFlag() );
  auto valueRef = static_cast<detail::BoundValueRefBase *>( m_ref.get() );

  auto result = valueRef->setValue( remainingTokens->token );
  if ( !result )
    return InternalParseResult( result );
  else
    return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
}
                           };

inline auto normaliseOpt( std::string const &optName ) -> std::string
{
#ifdef CATCH_PLATFORM_WINDOWS
  if ( optName[0] == '/' )
    return "-" + optName.substr( 1 );
  else
#endif
    return optName;
}

class Opt : public ParserRefImpl<Opt>
{
  protected:
  std::vector<std::string> m_optNames;

  public:
  template<typename LambdaT>
explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}

explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}

template<typename LambdaT>
Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}

template<typename T>
Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}

auto operator[]( std::string const &optName ) -> Opt &
{
  m_optNames.push_back( optName );
  return *this;
}

auto getHelpColumns() const -> std::vector<HelpColumns>
{
  std::ostringstream oss;
  bool first = true;
  for ( auto const &opt : m_optNames )
    {
      if (first)
        first = false;
      else
        oss << ", ";
      oss << opt;
    }
  if ( !m_hint.empty() )
    oss << " <" << m_hint << ">";
  return { { oss.str(), m_description } };
}

auto isMatch( std::string const &optToken ) const -> bool
{
  auto normalisedToken = normaliseOpt( optToken );
  for ( auto const &name : m_optNames )
    {
      if ( normaliseOpt( name ) == normalisedToken )
        return true;
    }
  return false;
}

using ParserBase::parse;

auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override
{
  auto validationResult = validate();
  if ( !validationResult )
    return InternalParseResult( validationResult );

  auto remainingTokens = tokens;
  if ( remainingTokens && remainingTokens->type == TokenType::Option )
    {
      auto const &token = *remainingTokens;
      if ( isMatch(token.token ) )
        {
          if ( m_ref->isFlag() )
            {
              auto flagRef = static_cast<detail::BoundFlagRefBase *>( m_ref.get() );
              auto result = flagRef->setFlag( true );
              if ( !result )
                return InternalParseResult( result );
              if ( result.value() == ParseResultType::ShortCircuitAll )
                return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
            }
          else
            {
              auto valueRef = static_cast<detail::BoundValueRefBase *>( m_ref.get() );
              ++remainingTokens;
              if ( !remainingTokens )
                return InternalParseResult::runtimeError( "Expected argument following " + token.token );
              auto const &argToken = *remainingTokens;
              if ( argToken.type != TokenType::Argument )
                return InternalParseResult::runtimeError( "Expected argument following " + token.token );
              auto result = valueRef->setValue( argToken.token );
              if ( !result )
                return InternalParseResult( result );
              if ( result.value() == ParseResultType::ShortCircuitAll )
                return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );
            }
          return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );
        }
    }
  return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );
}

auto validate() const -> Result override
{
  if ( m_optNames.empty() )
    return Result::logicError( "No options supplied to Opt" );
  for ( auto const &name : m_optNames )
    {
      if ( name.empty() )
        return Result::logicError( "Option name cannot be empty" );
#ifdef CATCH_PLATFORM_WINDOWS
      if ( name[0] != '-' && name[0] != '/' )
        return Result::logicError( "Option name must begin with '-' or '/'" );
#else
      if ( name[0] != '-' )
        return Result::logicError( "Option name must begin with '-'" );
#endif
    }
  return ParserRefImpl::validate();
}
                           };

struct Help : Opt
{
  Help( bool &showHelpFlag )
  :   Opt([&]( bool flag )
{
  showHelpFlag = flag;
  return ParserResult::ok( ParseResultType::ShortCircuitAll );
})
{
  static_cast<Opt &>( *this )
  ("display usage information")
  ["-?"]["-h"]["--help"]
  .optional();
}
           };

struct Parser : ParserBase
{

  mutable ExeName m_exeName;
  std::vector<Opt> m_options;
  std::vector<Arg> m_args;

  auto operator|=( ExeName const &exeName ) -> Parser &
{
  m_exeName = exeName;
  return *this;
}

auto operator|=( Arg const &arg ) -> Parser &
{
  m_args.push_back(arg);
  return *this;
}

auto operator|=( Opt const &opt ) -> Parser &
{
  m_options.push_back(opt);
  return *this;
}

auto operator|=( Parser const &other ) -> Parser &
{
  m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
  m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
  return *this;
}

template<typename T>
auto operator|( T const &other ) const -> Parser
{
  return Parser( *this ) |= other;
}

// Forward deprecated interface with '+' instead of '|'
template<typename T>
auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }
template<typename T>
auto operator+( T const &other ) const -> Parser
{
  return operator|( other );
}

auto getHelpColumns() const -> std::vector<HelpColumns>
{
  std::vector<HelpColumns> cols;
  for (auto const &o : m_options)
    {
      auto childCols = o.getHelpColumns();
      cols.insert( cols.end(), childCols.begin(), childCols.end() );
    }
  return cols;
}

void writeToStream( std::ostream &os ) const
{
  if (!m_exeName.name().empty())
    {
      os << "usage:\n" << "  " << m_exeName.name() << " ";
                                bool required = true, first = true;
                                for ( auto const &arg : m_args )
        {
          if (first)
            first = false;
          else
            os << " ";
          if ( arg.isOptional() && required )
            {
              os << "[";
              required = false;
            }
          os << "<" << arg.hint() << ">";
                     if ( arg.cardinality() == 0 )
                       os << " ... ";
        }
                 if ( !required )
                   os << "]";
                 if ( !m_options.empty() )
                   os << " options";
                 os << "\n\nwhere options are:" << std::endl;
    }

                 auto rows = getHelpColumns();
             size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;
             size_t optWidth = 0;
             for ( auto const &cols : rows )
               optWidth = (std::max)(optWidth, cols.left.size() + 2);

             optWidth = (std::min)(optWidth, consoleWidth/2);

             for ( auto const &cols : rows )
    {
      auto row =
      TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +
      TextFlow::Spacer(4) +
      TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );
      os << row << std::endl;
    }
}

friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream &
{
  parser.writeToStream( os );
  return os;
}

auto validate() const -> Result override
{
  for ( auto const &opt : m_options )
    {
      auto result = opt.validate();
      if ( !result )
        return result;
    }
  for ( auto const &arg : m_args )
    {
      auto result = arg.validate();
      if ( !result )
        return result;
    }
  return Result::ok();
}

using ParserBase::parse;

auto parse( std::string const &exeName, TokenStream const &tokens ) const -> InternalParseResult override
{

  struct ParserInfo
  {
    ParserBase const *parser = nullptr;
    size_t count = 0;
  };
  const size_t totalParsers = m_options.size() + m_args.size();
  assert( totalParsers < 512 );
  // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
  ParserInfo parseInfos[512];

  {
    size_t i = 0;
    for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
    for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
  }

  m_exeName.set( exeName );

  auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
  while ( result.value().remainingTokens() )
    {
      bool tokenParsed = false;

      for ( size_t i = 0; i < totalParsers; ++i )
        {
          auto  &parseInfo = parseInfos[i];
          if ( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() )
            {
              result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
              if (!result)
                return result;
              if (result.value().type() != ParseResultType::NoMatch)
                {
                  tokenParsed = true;
                  ++parseInfo.count;
                  break;
                }
            }
        }

      if ( result.value().type() == ParseResultType::ShortCircuitAll )
        return result;
      if ( !tokenParsed )
        return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token );
    }
  // !TBD Check missing required options
  return result;
}
   };

template<typename DerivedT>
template<typename T>
auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser
{
  return Parser() | static_cast<DerivedT const &>( *this ) | other;
}
                             } // namespace detail

// A Combined parser
using detail::Parser;

// A parser for options
using detail::Opt;

// A parser for arguments
using detail::Arg;

// Wrapper for argc, argv from main()
using detail::Args;

// Specifies the name of the executable
using detail::ExeName;

// Convenience wrapper for option parser that specifies the help option
using detail::Help;

// enum of result types from a parse
using detail::ParseResultType;

// Result type for parser operation
using detail::ParserResult;

                         }
        } // namespace Catch::clara

// end clara.hpp
#ifdef __clang__
#pragma clang diagnostic pop
#endif

// Restore Clara's value for console width, if present
#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
#endif

// end catch_clara.h
namespace Catch
{

  clara::Parser makeCommandLineParser( ConfigData &config );

} // end namespace Catch

// end catch_commandline.h
#include <fstream>
#include <ctime>

namespace Catch
{

  clara::Parser makeCommandLineParser( ConfigData &config )
{

  using namespace clara;

  auto const setWarning = [&]( std::string const& warning )
  {
    auto warningSet = [&]()
    {
      if ( warning == "NoAssertions" )
        return WarnAbout::NoAssertions;

      if ( warning == "NoTests" )
        return WarnAbout::NoTests;

      return WarnAbout::Nothing;
    }();

    if (warningSet == WarnAbout::Nothing)
      return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" );
    config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet );
    return ParserResult::ok( ParseResultType::Matched );
  };
  auto const loadTestNamesFromFile = [&]( std::string const& filename )
  {
    std::ifstream f( filename.c_str() );
    if ( !f.is_open() )
      return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" );

    std::string line;
    while ( std::getline( f, line ) )
      {
        line = trim(line);
        if ( !line.empty() && !startsWith( line, '#' ) )
          {
            if ( !startsWith( line, '"' ) )
              line = '"' + line + '"';
            config.testsOrTags.push_back( line + ',' );
          }
      }
    return ParserResult::ok( ParseResultType::Matched );
  };
  auto const setTestOrder = [&]( std::string const& order )
  {
    if ( startsWith( "declared", order ) )
      config.runOrder = RunTests::InDeclarationOrder;
    else if ( startsWith( "lexical", order ) )
      config.runOrder = RunTests::InLexicographicalOrder;
    else if ( startsWith( "random", order ) )
      config.runOrder = RunTests::InRandomOrder;
    else
      return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" );
    return ParserResult::ok( ParseResultType::Matched );
  };
  auto const setRngSeed = [&]( std::string const& seed )
  {
    if ( seed != "time" )
      return clara::detail::convertInto( seed, config.rngSeed );
    config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );
    return ParserResult::ok( ParseResultType::Matched );
  };
  auto const setColourUsage = [&]( std::string const& useColour )
  {
    auto mode = toLower( useColour );

    if ( mode == "yes" )
      config.useColour = UseColour::Yes;
    else if ( mode == "no" )
      config.useColour = UseColour::No;
    else if ( mode == "auto" )
      config.useColour = UseColour::Auto;
    else
      return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" );
    return ParserResult::ok( ParseResultType::Matched );
  };
  auto const setWaitForKeypress = [&]( std::string const& keypress )
  {
    auto keypressLc = toLower( keypress );
    if ( keypressLc == "start" )
      config.waitForKeypress = WaitForKeypress::BeforeStart;
    else if ( keypressLc == "exit" )
      config.waitForKeypress = WaitForKeypress::BeforeExit;
    else if ( keypressLc == "both" )
      config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
    else
      return ParserResult::runtimeError( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" );
    return ParserResult::ok( ParseResultType::Matched );
  };
  auto const setVerbosity = [&]( std::string const& verbosity )
  {
    auto lcVerbosity = toLower( verbosity );
    if ( lcVerbosity == "quiet" )
      config.verbosity = Verbosity::Quiet;
    else if ( lcVerbosity == "normal" )
      config.verbosity = Verbosity::Normal;
    else if ( lcVerbosity == "high" )
      config.verbosity = Verbosity::High;
    else
      return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" );
    return ParserResult::ok( ParseResultType::Matched );
  };

  auto cli
  = ExeName( config.processName )
  | Help( config.showHelp )
  | Opt( config.listTests )
  ["-l"]["--list-tests"]
  ( "list all/matching test cases" )
  | Opt( config.listTags )
  ["-t"]["--list-tags"]
  ( "list all/matching tags" )
  | Opt( config.showSuccessfulTests )
  ["-s"]["--success"]
  ( "include successful tests in output" )
  | Opt( config.shouldDebugBreak )
  ["-b"]["--break"]
  ( "break into debugger on failure" )
  | Opt( config.noThrow )
  ["-e"]["--nothrow"]
  ( "skip exception tests" )
  | Opt( config.showInvisibles )
  ["-i"]["--invisibles"]
  ( "show invisibles (tabs, newlines)" )
  | Opt( config.outputFilename, "filename" )
  ["-o"]["--out"]
  ( "output filename" )
  | Opt( config.reporterName, "name" )
  ["-r"]["--reporter"]
  ( "reporter to use (defaults to console)" )
  | Opt( config.name, "name" )
  ["-n"]["--name"]
  ( "suite name" )
  | Opt( [&]( bool )
  {
    config.abortAfter = 1;
  } )
  ["-a"]["--abort"]
  ( "abort at first failure" )
  | Opt( [&]( int x )
  {
    config.abortAfter = x;
  }, "no. failures" )
  ["-x"]["--abortx"]
  ( "abort after x failures" )
  | Opt( setWarning, "warning name" )
  ["-w"]["--warn"]
  ( "enable warnings" )
  | Opt( [&]( bool flag )
  {
    config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never;
  }, "yes|no" )
  ["-d"]["--durations"]
  ( "show test durations" )
  | Opt( loadTestNamesFromFile, "filename" )
  ["-f"]["--input-file"]
  ( "load test names to run from a file" )
  | Opt( config.filenamesAsTags )
  ["-#"]["--filenames-as-tags"]
  ( "adds a tag for the filename" )
  | Opt( config.sectionsToRun, "section name" )
  ["-c"]["--section"]
  ( "specify section to run" )
  | Opt( setVerbosity, "quiet|normal|high" )
  ["-v"]["--verbosity"]
  ( "set output verbosity" )
  | Opt( config.listTestNamesOnly )
  ["--list-test-names-only"]
  ( "list all/matching test cases names only" )
  | Opt( config.listReporters )
  ["--list-reporters"]
  ( "list all reporters" )
  | Opt( setTestOrder, "decl|lex|rand" )
  ["--order"]
  ( "test case order (defaults to decl)" )
  | Opt( setRngSeed, "'time'|number" )
  ["--rng-seed"]
  ( "set a specific seed for random numbers" )
  | Opt( setColourUsage, "yes|no" )
  ["--use-colour"]
  ( "should output be colourised" )
  | Opt( config.libIdentify )
  ["--libidentify"]
  ( "report name and version according to libidentify standard" )
  | Opt( setWaitForKeypress, "start|exit|both" )
  ["--wait-for-keypress"]
  ( "waits for a keypress before exiting" )
  | Opt( config.benchmarkResolutionMultiple, "multiplier" )
  ["--benchmark-resolution-multiple"]
  ( "multiple of clock resolution to run benchmarks" )

  | Arg( config.testsOrTags, "test name|pattern|tags" )
  ( "which test or tests to use" );

  return cli;
}

                            } // end namespace Catch
// end catch_commandline.cpp
// start catch_common.cpp

#include <cstring>
#include <ostream>

namespace Catch
{

  bool SourceLineInfo::empty() const noexcept
{
  return file[0] == '\0';
}
bool SourceLineInfo::operator == ( SourceLineInfo const &other ) const noexcept
{
  return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
}
bool SourceLineInfo::operator < ( SourceLineInfo const &other ) const noexcept
{
  return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0));
}

              std::ostream &operator << ( std::ostream &os, SourceLineInfo const &info )
{
#ifndef __GNUG__
  os << info.file << '(' << info.line << ')';
#else
  os << info.file << ':' << info.line;
#endif
                          return os;
}

                        std::string StreamEndStop::operator+() const
{
  return std::string();
}

NonCopyable::NonCopyable() = default;
NonCopyable::~NonCopyable() = default;

                                    }
// end catch_common.cpp
// start catch_config.cpp

// start catch_enforce.h

#include <stdexcept>

#define CATCH_PREPARE_EXCEPTION( type, msg ) \
  type( ( Catch::ReusableStringStream() << msg ).str() )
#define CATCH_INTERNAL_ERROR( msg ) \
  throw CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg);
#define CATCH_ERROR( msg ) \
  throw CATCH_PREPARE_EXCEPTION( std::domain_error, msg )
#define CATCH_ENFORCE( condition, msg ) \
  do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false)

// end catch_enforce.h
namespace Catch
{

  Config::Config( ConfigData const &data )
  :   m_data( data ),
  m_stream( openStream() )
{
  TestSpecParser parser(ITagAliasRegistry::get());
  if (data.testsOrTags.empty())
    {
      parser.parse("~[.]"); // All not hidden tests
    }
  else
    {
      m_hasTestFilters = true;
      for ( auto const &testOrTags : data.testsOrTags )
        parser.parse( testOrTags );
    }
  m_testSpec = parser.testSpec();
}

std::string const &Config::getFilename() const
{
  return m_data.outputFilename ;
}

bool Config::listTests() const
{
  return m_data.listTests;
}
bool Config::listTestNamesOnly() const
{
  return m_data.listTestNamesOnly;
}
bool Config::listTags() const
{
  return m_data.listTags;
}
bool Config::listReporters() const
{
  return m_data.listReporters;
}

std::string Config::getProcessName() const
{
  return m_data.processName;
}
std::string const &Config::getReporterName() const
{
  return m_data.reporterName;
}

std::vector<std::string> const &Config::getTestsOrTags() const
{
  return m_data.testsOrTags;
}
std::vector<std::string> const &Config::getSectionsToRun() const
{
  return m_data.sectionsToRun;
}

TestSpec const &Config::testSpec() const
{
  return m_testSpec;
}
bool Config::hasTestFilters() const
{
  return m_hasTestFilters;
}

bool Config::showHelp() const
{
  return m_data.showHelp;
}

// IConfig interface
bool Config::allowThrows() const
{
  return !m_data.noThrow;
}
std::ostream &Config::stream() const
{
  return m_stream->stream();
}
std::string Config::name() const
{
  return m_data.name.empty() ? m_data.processName : m_data.name;
}
bool Config::includeSuccessfulResults() const
{
  return m_data.showSuccessfulTests;
}
bool Config::warnAboutMissingAssertions() const
{
  return !!(m_data.warnings & WarnAbout::NoAssertions);
}
bool Config::warnAboutNoTests() const
{
  return !!(m_data.warnings & WarnAbout::NoTests);
}
ShowDurations::OrNot Config::showDurations() const
{
  return m_data.showDurations;
}
RunTests::InWhatOrder Config::runOrder() const
{
  return m_data.runOrder;
}
unsigned int Config::rngSeed() const
{
  return m_data.rngSeed;
}
int Config::benchmarkResolutionMultiple() const
{
  return m_data.benchmarkResolutionMultiple;
}
UseColour::YesOrNo Config::useColour() const
{
  return m_data.useColour;
}
bool Config::shouldDebugBreak() const
{
  return m_data.shouldDebugBreak;
}
int Config::abortAfter() const
{
  return m_data.abortAfter;
}
bool Config::showInvisibles() const
{
  return m_data.showInvisibles;
}
Verbosity Config::verbosity() const
{
  return m_data.verbosity;
}

IStream const *Config::openStream()
{
  return Catch::makeStream(m_data.outputFilename);
}

           } // end namespace Catch
// end catch_config.cpp
// start catch_console_colour.cpp

#if defined(__clang__)
#    pragma clang diagnostic push
#    pragma clang diagnostic ignored "-Wexit-time-destructors"
#endif

// start catch_errno_guard.h

namespace Catch
{

  class ErrnoGuard
  {
    public:
    ErrnoGuard();
    ~ErrnoGuard();
    private:
    int m_oldErrno;
  };

}

// end catch_errno_guard.h
#include <sstream>

namespace Catch
{
  namespace
  {

    struct IColourImpl
    {
      virtual ~IColourImpl() = default;
      virtual void use( Colour::Code _colourCode ) = 0;
    };

    struct NoColourImpl : IColourImpl
    {
void use( Colour::Code ) {}

static IColourImpl *instance()
{
  static NoColourImpl s_instance;
  return &s_instance;
}
    };

  } // anon namespace
} // namespace Catch

#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
#   ifdef CATCH_PLATFORM_WINDOWS
#       define CATCH_CONFIG_COLOUR_WINDOWS
#   else
#       define CATCH_CONFIG_COLOUR_ANSI
#   endif
#endif

#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////

namespace Catch
{
  namespace
  {

    class Win32ColourImpl : public IColourImpl
    {
      public:
      Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
{
  CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
  GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
  originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
  originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
}

virtual void use( Colour::Code _colourCode ) override
{
  switch ( _colourCode )
    {
      case Colour::None:
        return setTextAttribute( originalForegroundAttributes );
      case Colour::White:
        return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
      case Colour::Red:
        return setTextAttribute( FOREGROUND_RED );
      case Colour::Green:
        return setTextAttribute( FOREGROUND_GREEN );
      case Colour::Blue:
        return setTextAttribute( FOREGROUND_BLUE );
      case Colour::Cyan:
        return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
      case Colour::Yellow:
        return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
      case Colour::Grey:
        return setTextAttribute( 0 );

      case Colour::LightGrey:
        return setTextAttribute( FOREGROUND_INTENSITY );
      case Colour::BrightRed:
        return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
      case Colour::BrightGreen:
        return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
      case Colour::BrightWhite:
        return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
      case Colour::BrightYellow:
        return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );

      case Colour::Bright:
        CATCH_INTERNAL_ERROR( "not a colour" );

      default:
        CATCH_ERROR( "Unknown colour requested" );
    }
}

private:
void setTextAttribute( WORD _textAttribute )
{
  SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
}
HANDLE stdoutHandle;
WORD originalForegroundAttributes;
WORD originalBackgroundAttributes;
    };

IColourImpl *platformColourInstance()
{
  static Win32ColourImpl s_instance;

  IConfigPtr config = getCurrentContext().getConfig();
  UseColour::YesOrNo colourMode = config
  ? config->useColour()
  : UseColour::Auto;
  if ( colourMode == UseColour::Auto )
    colourMode = UseColour::Yes;
  return colourMode == UseColour::Yes
  ? &s_instance
  : NoColourImpl::instance();
}

  } // end anon namespace
} // end namespace Catch

#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////

#include <unistd.h>

namespace Catch
{
  namespace
  {

    // use POSIX/ ANSI console terminal codes
    // Thanks to Adam Strzelecki for original contribution
    // (http://github.com/nanoant)
    // https://github.com/philsquared/Catch/pull/131
    class PosixColourImpl : public IColourImpl
    {
      public:
      virtual void use( Colour::Code _colourCode ) override
{
  switch ( _colourCode )
    {
      case Colour::None:
      case Colour::White:
        return setColour( "[0m" );
      case Colour::Red:
        return setColour( "[0;31m" );
      case Colour::Green:
        return setColour( "[0;32m" );
      case Colour::Blue:
        return setColour( "[0;34m" );
      case Colour::Cyan:
        return setColour( "[0;36m" );
      case Colour::Yellow:
        return setColour( "[0;33m" );
      case Colour::Grey:
        return setColour( "[1;30m" );

      case Colour::LightGrey:
        return setColour( "[0;37m" );
      case Colour::BrightRed:
        return setColour( "[1;31m" );
      case Colour::BrightGreen:
        return setColour( "[1;32m" );
      case Colour::BrightWhite:
        return setColour( "[1;37m" );
      case Colour::BrightYellow:
        return setColour( "[1;33m" );

      case Colour::Bright:
        CATCH_INTERNAL_ERROR( "not a colour" );
      default:
        CATCH_INTERNAL_ERROR( "Unknown colour requested" );
    }
}
static IColourImpl *instance()
{
  static PosixColourImpl s_instance;
  return &s_instance;
}

private:
void setColour( const char *_escapeCode )
{
  Catch::cout() << '\033' << _escapeCode;
}
                        };

bool useColourOnPlatform()
{
  return
#ifdef CATCH_PLATFORM_MAC
  !isDebuggerActive() &&
#endif
#if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
  isatty(STDOUT_FILENO)
#else
  false
#endif
  ;
}
IColourImpl *platformColourInstance()
{
  ErrnoGuard guard;
  IConfigPtr config = getCurrentContext().getConfig();
  UseColour::YesOrNo colourMode = config
  ? config->useColour()
  : UseColour::Auto;
  if ( colourMode == UseColour::Auto )
    colourMode = useColourOnPlatform()
    ? UseColour::Yes
    : UseColour::No;
  return colourMode == UseColour::Yes
  ? PosixColourImpl::instance()
  : NoColourImpl::instance();
}

              } // end anon namespace
    } // end namespace Catch

#else  // not Windows or ANSI ///////////////////////////////////////////////

namespace Catch
{

  static IColourImpl *platformColourInstance()
{
  return NoColourImpl::instance();
}

} // end namespace Catch

#endif // Windows/ ANSI/ None

namespace Catch
{

  Colour::Colour( Code _colourCode )
{
  use( _colourCode );
}
Colour::Colour( Colour&& rhs ) noexcept
{
  m_moved = rhs.m_moved;
  rhs.m_moved = true;
}
Colour &Colour::operator=( Colour&& rhs ) noexcept
{
  m_moved = rhs.m_moved;
  rhs.m_moved  = true;
  return *this;
}

Colour::~Colour()
{
  if ( !m_moved ) use( None );
}

void Colour::use( Code _colourCode )
{
  static IColourImpl *impl = platformColourInstance();
  impl->use( _colourCode );
}

std::ostream &operator << ( std::ostream &os, Colour const &)
{
  return os;
}

                       } // end namespace Catch

#if defined(__clang__)
#    pragma clang diagnostic pop
#endif

// end catch_console_colour.cpp
// start catch_context.cpp

namespace Catch
{

  class Context : public IMutableContext, NonCopyable
  {

    public: // IContext
    virtual IResultCapture *getResultCapture() override
{
  return m_resultCapture;
}
virtual IRunner *getRunner() override
{
  return m_runner;
}

virtual IConfigPtr const &getConfig() const override
{
  return m_config;
}

virtual ~Context() override;

public: // IMutableContext
virtual void setResultCapture( IResultCapture *resultCapture ) override
{
  m_resultCapture = resultCapture;
}
virtual void setRunner( IRunner *runner ) override
{
  m_runner = runner;
}
virtual void setConfig( IConfigPtr const &config ) override
{
  m_config = config;
}

friend IMutableContext &getCurrentMutableContext();

private:
IConfigPtr m_config;
IRunner *m_runner = nullptr;
IResultCapture *m_resultCapture = nullptr;
  };

IMutableContext *IMutableContext::currentContext = nullptr;

void IMutableContext::createContext()
{
  currentContext = new Context();
}

void cleanUpContext()
{
  delete IMutableContext::currentContext;
  IMutableContext::currentContext = nullptr;
}
IContext::~IContext() = default;
IMutableContext::~IMutableContext() = default;
Context::~Context() = default;
}
// end catch_context.cpp
// start catch_debug_console.cpp

// start catch_debug_console.h

#include <string>

namespace Catch
{
  void writeToDebugConsole( std::string const &text );
}

// end catch_debug_console.h
#ifdef CATCH_PLATFORM_WINDOWS

namespace Catch
{
  void writeToDebugConsole( std::string const &text )
{
  ::OutputDebugStringA( text.c_str() );
}
}

#else

namespace Catch
{
  void writeToDebugConsole( std::string const &text )
{
  // !TBD: Need a version for Mac/ XCode and other IDEs
  Catch::cout() << text;
}
              }

#endif // Platform
// end catch_debug_console.cpp
// start catch_debugger.cpp

#ifdef CATCH_PLATFORM_MAC

#  include <assert.h>
#  include <stdbool.h>
#  include <sys/types.h>
#  include <unistd.h>
#  include <sys/sysctl.h>
#  include <cstddef>
#  include <ostream>

namespace Catch
{

  // The following function is taken directly from the following technical note:
  // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html

  // Returns true if the current process is being debugged (either
  // running under the debugger or has a debugger attached post facto).
  bool isDebuggerActive()
{

  int                 mib[4];
  struct kinfo_proc   info;
  std::size_t         size;

  // Initialize the flags so that, if sysctl fails for some bizarre
  // reason, we get a predictable result.

  info.kp_proc.p_flag = 0;

  // Initialize mib, which tells sysctl the info we want, in this case
  // we're looking for information about a specific process ID.

  mib[0] = CTL_KERN;
  mib[1] = KERN_PROC;
  mib[2] = KERN_PROC_PID;
  mib[3] = getpid();

  // Call sysctl.

  size = sizeof(info);
  if ( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 )
    {
      Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
                     return false;
    }

                 // We're being debugged if the P_TRACED flag is set.

                 return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
}
                                                                                               } // namespace Catch

#elif defined(CATCH_PLATFORM_LINUX)
#include <fstream>
#include <string>

namespace Catch
{
  // The standard POSIX way of detecting a debugger is to attempt to
  // ptrace() the process, but this needs to be done from a child and not
  // this process itself to still allow attaching to this process later
  // if wanted, so is rather heavy. Under Linux we have the PID of the
  // "debugger" (which doesn't need to be gdb, of course, it could also
  // be strace, for example) in /proc/$PID/status, so just get it from
  // there instead.
  bool isDebuggerActive()
{
  // Libstdc++ has a bug, where std::ifstream sets errno to 0
  // This way our users can properly assert over errno values
  ErrnoGuard guard;
  std::ifstream in("/proc/self/status");
  for ( std::string line; std::getline(in, line); )
    {
      static const int PREFIX_LEN = 11;
      if ( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 )
        {
          // We're traced if the PID is not 0 and no other PID starts
          // with 0 digit, so it's enough to check for just a single
          // character.
          return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
        }
    }

  return false;
}
} // namespace Catch
#elif defined(_MSC_VER)
extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
namespace Catch
{
  bool isDebuggerActive()
  {
    return IsDebuggerPresent() != 0;
  }
}
#elif defined(__MINGW32__)
extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
namespace Catch
{
  bool isDebuggerActive()
  {
    return IsDebuggerPresent() != 0;
  }
}
#else
namespace Catch
{
  bool isDebuggerActive()
{
  return false;
}
}
#endif // Platform
// end catch_debugger.cpp
// start catch_decomposer.cpp

namespace Catch
{

  ITransientExpression::~ITransientExpression() = default;

  void formatReconstructedExpression( std::ostream &os, std::string const &lhs, StringRef op, std::string const &rhs )
{
  if ( lhs.size() + rhs.size() < 40 &&
                                 lhs.find('\n') == std::string::npos &&
                                 rhs.find('\n') == std::string::npos )
         os << lhs << " " << op << " " << rhs;
                               else
                                 os << lhs << "\n" << op << "\n" << rhs;
}
                                                             }
// end catch_decomposer.cpp
// start catch_errno_guard.cpp

#include <cerrno>

                                                namespace Catch
                                                {
ErrnoGuard::ErrnoGuard():m_oldErrno(errno) {}
ErrnoGuard::~ErrnoGuard()
{
  errno = m_oldErrno;
}
                                                }
// end catch_errno_guard.cpp
// start catch_exception_translator_registry.cpp

// start catch_exception_translator_registry.h

#include <vector>
#include <string>
#include <memory>

namespace Catch
{

  class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry
  {
    public:
    ~ExceptionTranslatorRegistry();
    virtual void registerTranslator( const IExceptionTranslator *translator );
    virtual std::string translateActiveException() const override;
    std::string tryTranslators() const;

    private:
    std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;
                               };
               }

// end catch_exception_translator_registry.h
#ifdef __OBJC__
#import "Foundation/Foundation.h"
#endif

namespace Catch
{

  ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry()
  {
  }

  void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator *translator )
  {
    m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
  }

  std::string ExceptionTranslatorRegistry::translateActiveException() const
  {
    try
      {
#ifdef __OBJC__
        // In Objective-C try objective-c exceptions first
        @try
          {
            return tryTranslators();
          }
        @catch (NSException *exception)
          {
            return Catch::Detail::stringify( [exception description] );
          }
#else
        // Compiling a mixed mode project with MSVC means that CLR
        // exceptions will be caught in (...) as well. However, these
        // do not fill-in std::current_exception and thus lead to crash
        // when attempting rethrow.
        // /EHa switch also causes structured exceptions to be caught
        // here, but they fill-in current_exception properly, so
        // at worst the output should be a little weird, instead of
        // causing a crash.
        if (std::current_exception() == nullptr)
          {
            return "Non C++ exception. Possibly a CLR exception.";
          }
        return tryTranslators();
#endif
      }
    catch ( TestFailureException &)
      {
        std::rethrow_exception(std::current_exception());
      }
    catch ( std::exception &ex )
      {
        return ex.what();
      }
    catch ( std::string &msg )
      {
        return msg;
      }
    catch ( const char *msg )
      {
        return msg;
      }
    catch (...)
      {
        return "Unknown exception";
      }
  }

  std::string ExceptionTranslatorRegistry::tryTranslators() const
  {
    if ( m_translators.empty() )
      std::rethrow_exception(std::current_exception());
    else
      return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
  }
}
// end catch_exception_translator_registry.cpp
// start catch_fatal_condition.cpp

#if defined(__GNUC__)
#    pragma GCC diagnostic push
#    pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#endif

#if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )

namespace
{
  // Report the error condition
  void reportFatal( char const *const message )
{
  Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
}
}

#endif // signals/SEH handling

#if defined( CATCH_CONFIG_WINDOWS_SEH )

namespace Catch
{
  struct SignalDefs
  {
    DWORD id;
    const char *name;
  };

  // There is no 1-1 mapping between signals and windows exceptions.
  // Windows can easily distinguish between SO and SigSegV,
  // but SigInt, SigTerm, etc are handled differently.
  static SignalDefs signalDefs[] =
{
  { EXCEPTION_ILLEGAL_INSTRUCTION,  "SIGILL - Illegal instruction signal" },
  { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" },
  { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" },
  { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
};

LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo)
{
  for (auto const &def : signalDefs)
    {
      if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id)
        {
          reportFatal(def.name);
        }
    }
  // If its not an exception we care about, pass it along.
  // This stops us from eating debugger breaks etc.
  return EXCEPTION_CONTINUE_SEARCH;
}

FatalConditionHandler::FatalConditionHandler()
{
  isSet = true;
  // 32k seems enough for Catch to handle stack overflow,
  // but the value was found experimentally, so there is no strong guarantee
  guaranteeSize = 32 * 1024;
  exceptionHandlerHandle = nullptr;
  // Register as first handler in current chain
  exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
  // Pass in guarantee size to be filled
  SetThreadStackGuarantee(&guaranteeSize);
}

void FatalConditionHandler::reset()
{
  if (isSet)
    {
      RemoveVectoredExceptionHandler(exceptionHandlerHandle);
      SetThreadStackGuarantee(&guaranteeSize);
      exceptionHandlerHandle = nullptr;
      isSet = false;
    }
}

FatalConditionHandler::~FatalConditionHandler()
{
  reset();
}

bool FatalConditionHandler::isSet = false;
ULONG FatalConditionHandler::guaranteeSize = 0;
PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;

} // namespace Catch

#elif defined( CATCH_CONFIG_POSIX_SIGNALS )

namespace Catch
{

  struct SignalDefs
  {
    int id;
    const char *name;
  };

  // 32kb for the alternate stack seems to be sufficient. However, this value
  // is experimentally determined, so that's not guaranteed.
  constexpr static std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;

  static SignalDefs signalDefs[] =
{
  { SIGINT,  "SIGINT - Terminal interrupt signal" },
  { SIGILL,  "SIGILL - Illegal instruction signal" },
  { SIGFPE,  "SIGFPE - Floating point error signal" },
  { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
  { SIGTERM, "SIGTERM - Termination request signal" },
  { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
};

void FatalConditionHandler::handleSignal( int sig )
{
  char const *name = "<unknown signal>";
  for (auto const &def : signalDefs)
    {
      if (sig == def.id)
        {
          name = def.name;
          break;
        }
    }
  reset();
  reportFatal(name);
  raise( sig );
}

FatalConditionHandler::FatalConditionHandler()
{
  isSet = true;
  stack_t sigStack;
  sigStack.ss_sp = altStackMem;
  sigStack.ss_size = sigStackSize;
  sigStack.ss_flags = 0;
  sigaltstack(&sigStack, &oldSigStack);
  struct sigaction sa = { };

  sa.sa_handler = handleSignal;
  sa.sa_flags = SA_ONSTACK;
  for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i)
    {
      sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
    }
}

FatalConditionHandler::~FatalConditionHandler()
{
  reset();
}

void FatalConditionHandler::reset()
{
  if ( isSet )
    {
      // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
      for ( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
        {
          sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
        }
      // Return the old stack
      sigaltstack(&oldSigStack, nullptr);
      isSet = false;
    }
}

bool FatalConditionHandler::isSet = false;
struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
stack_t FatalConditionHandler::oldSigStack = {};
char FatalConditionHandler::altStackMem[sigStackSize] = {};

    } // namespace Catch

#else

namespace Catch
{
void FatalConditionHandler::reset() {}
}

#endif // signals/SEH handling

#if defined(__GNUC__)
#    pragma GCC diagnostic pop
#endif
// end catch_fatal_condition.cpp
// start catch_interfaces_capture.cpp

namespace Catch
{
  IResultCapture::~IResultCapture() = default;
}
// end catch_interfaces_capture.cpp
// start catch_interfaces_config.cpp

namespace Catch
{
  IConfig::~IConfig() = default;
}
// end catch_interfaces_config.cpp
// start catch_interfaces_exception.cpp

namespace Catch
{
  IExceptionTranslator::~IExceptionTranslator() = default;
  IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;
}
// end catch_interfaces_exception.cpp
// start catch_interfaces_registry_hub.cpp

namespace Catch
{
  IRegistryHub::~IRegistryHub() = default;
  IMutableRegistryHub::~IMutableRegistryHub() = default;
}
// end catch_interfaces_registry_hub.cpp
// start catch_interfaces_reporter.cpp

// start catch_reporter_listening.h

namespace Catch
{

  class ListeningReporter : public IStreamingReporter
  {
    using Reporters = std::vector<IStreamingReporterPtr>;
    Reporters m_listeners;
    IStreamingReporterPtr m_reporter = nullptr;

    public:
    void addListener( IStreamingReporterPtr &&listener );
    void addReporter( IStreamingReporterPtr &&reporter );

    public: // IStreamingReporter

    ReporterPreferences getPreferences() const override;

    void noMatchingTestCases( std::string const &spec ) override;

    static std::set<Verbosity> getSupportedVerbosities();

    void benchmarkStarting( BenchmarkInfo const &benchmarkInfo ) override;
    void benchmarkEnded( BenchmarkStats const &benchmarkStats ) override;

    void testRunStarting( TestRunInfo const &testRunInfo ) override;
    void testGroupStarting( GroupInfo const &groupInfo ) override;
    void testCaseStarting( TestCaseInfo const &testInfo ) override;
    void sectionStarting( SectionInfo const &sectionInfo ) override;
    void assertionStarting( AssertionInfo const &assertionInfo ) override;

    // The return value indicates if the messages buffer should be cleared:
    bool assertionEnded( AssertionStats const &assertionStats ) override;
    void sectionEnded( SectionStats const &sectionStats ) override;
    void testCaseEnded( TestCaseStats const &testCaseStats ) override;
    void testGroupEnded( TestGroupStats const &testGroupStats ) override;
    void testRunEnded( TestRunStats const &testRunStats ) override;

    void skipTest( TestCaseInfo const &testInfo ) override;
    bool isMulti() const override;

                   };

                                 } // end namespace Catch

// end catch_reporter_listening.h
namespace Catch
{

  ReporterConfig::ReporterConfig( IConfigPtr const &_fullConfig )
    :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}

  ReporterConfig::ReporterConfig( IConfigPtr const &_fullConfig, std::ostream &_stream )
    :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}

  std::ostream &ReporterConfig::stream() const
  {
    return *m_stream;
  }
  IConfigPtr ReporterConfig::fullConfig() const
  {
    return m_fullConfig;
  }

  TestRunInfo::TestRunInfo( std::string const &_name ) : name( _name ) {}

  GroupInfo::GroupInfo(  std::string const &_name,
                         std::size_t _groupIndex,
                         std::size_t _groupsCount )
    :   name( _name ),
        groupIndex( _groupIndex ),
        groupsCounts( _groupsCount )
  {}

  AssertionStats::AssertionStats( AssertionResult const &_assertionResult,
                                  std::vector<MessageInfo> const &_infoMessages,
                                  Totals const &_totals )
    :   assertionResult( _assertionResult ),
        infoMessages( _infoMessages ),
        totals( _totals )
  {
    assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;

    if ( assertionResult.hasMessage() )
      {
        // Copy message into messages list.
        // !TBD This should have been done earlier, somewhere
        MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
        builder << assertionResult.getMessage();
        builder.m_info.message = builder.m_stream.str();

        infoMessages.push_back( builder.m_info );
      }
  }

  AssertionStats::~AssertionStats() = default;

  SectionStats::SectionStats(  SectionInfo const &_sectionInfo,
                               Counts const &_assertions,
                               double _durationInSeconds,
                               bool _missingAssertions )
    :   sectionInfo( _sectionInfo ),
        assertions( _assertions ),
        durationInSeconds( _durationInSeconds ),
        missingAssertions( _missingAssertions )
  {}

  SectionStats::~SectionStats() = default;

  TestCaseStats::TestCaseStats(  TestCaseInfo const &_testInfo,
                                 Totals const &_totals,
                                 std::string const &_stdOut,
                                 std::string const &_stdErr,
                                 bool _aborting )
    : testInfo( _testInfo ),
      totals( _totals ),
      stdOut( _stdOut ),
      stdErr( _stdErr ),
      aborting( _aborting )
  {}

  TestCaseStats::~TestCaseStats() = default;

  TestGroupStats::TestGroupStats( GroupInfo const &_groupInfo,
                                  Totals const &_totals,
                                  bool _aborting )
    :   groupInfo( _groupInfo ),
        totals( _totals ),
        aborting( _aborting )
  {}

  TestGroupStats::TestGroupStats( GroupInfo const &_groupInfo )
    :   groupInfo( _groupInfo ),
        aborting( false )
  {}

  TestGroupStats::~TestGroupStats() = default;

  TestRunStats::TestRunStats(   TestRunInfo const &_runInfo,
                                Totals const &_totals,
                                bool _aborting )
    :   runInfo( _runInfo ),
        totals( _totals ),
        aborting( _aborting )
  {}

  TestRunStats::~TestRunStats() = default;

  void IStreamingReporter::fatalErrorEncountered( StringRef ) {}
  bool IStreamingReporter::isMulti() const
  {
    return false;
  }

  IReporterFactory::~IReporterFactory() = default;
  IReporterRegistry::~IReporterRegistry() = default;

} // end namespace Catch
// end catch_interfaces_reporter.cpp
// start catch_interfaces_runner.cpp

namespace Catch
{
  IRunner::~IRunner() = default;
}
// end catch_interfaces_runner.cpp
// start catch_interfaces_testcase.cpp

namespace Catch
{
  ITestInvoker::~ITestInvoker() = default;
  ITestCaseRegistry::~ITestCaseRegistry() = default;
}
// end catch_interfaces_testcase.cpp
// start catch_leak_detector.cpp

#ifdef CATCH_CONFIG_WINDOWS_CRTDBG
#include <crtdbg.h>

namespace Catch
{

  LeakDetector::LeakDetector()
{
  int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
  flag |= _CRTDBG_LEAK_CHECK_DF;
  flag |= _CRTDBG_ALLOC_MEM_DF;
  _CrtSetDbgFlag(flag);
  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
  _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
  // Change this to leaking allocation's number to break there
  _CrtSetBreakAlloc(-1);
}
}

#else

Catch::LeakDetector::LeakDetector() {}

#endif
// end catch_leak_detector.cpp
// start catch_list.cpp

// start catch_list.h

#include <set>

namespace Catch
{

  std::size_t listTests( Config const &config );

  std::size_t listTestsNamesOnly( Config const &config );

  struct TagInfo
  {
    void add( std::string const &spelling );
    std::string all() const;

    std::set<std::string> spellings;
    std::size_t count = 0;
            };

  std::size_t listTags( Config const &config );

  std::size_t listReporters( Config const & /*config*/ );

  Option<std::size_t> list( Config const &config );

        } // end namespace Catch

// end catch_list.h
// start catch_text.h

namespace Catch
{
  using namespace clara::TextFlow;
}

// end catch_text.h
#include <limits>
#include <algorithm>
#include <iomanip>

namespace Catch
{

  std::size_t listTests( Config const &config )
{
  TestSpec testSpec = config.testSpec();
  if ( config.hasTestFilters() )
    Catch::cout() << "Matching test cases:\n";
  else
    {
      Catch::cout() << "All available test cases:\n";
    }

  auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
  for ( auto const &testCaseInfo : matchedTestCases )
    {
      Colour::Code colour = testCaseInfo.isHidden()
      ? Colour::SecondaryText
      : Colour::None;
      Colour colourGuard( colour );

      Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n";
                     if ( config.verbosity() >= Verbosity::High )
        {
          Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;
                         std::string description = testCaseInfo.description;
                         if ( description.empty() )
                           description = "(NO DESCRIPTION)";
                         Catch::cout() << Column( description ).indent(4) << std::endl;
        }
                                    if ( !testCaseInfo.tags.empty() )
                                      Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n";
    }

                                               if ( !config.hasTestFilters() )
                                                 Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl;
                                                              else
                                                                Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl;
                                                                             return matchedTestCases.size();
}

                                                                           std::size_t listTestsNamesOnly( Config const &config )
{
  TestSpec testSpec = config.testSpec();
  std::size_t matchedTests = 0;
  std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
  for ( auto const &testCaseInfo : matchedTestCases )
    {
      matchedTests++;
      if ( startsWith( testCaseInfo.name, '#' ) )
        Catch::cout() << '"' << testCaseInfo.name << '"';
                            else
                              Catch::cout() << testCaseInfo.name;
                            if ( config.verbosity() >= Verbosity::High )
                              Catch::cout() << "\t@" << testCaseInfo.lineInfo;
                                           Catch::cout() << std::endl;
    }
                                       return matchedTests;
}

                                     void TagInfo::add( std::string const &spelling )
{
  ++count;
  spellings.insert( spelling );
}

std::string TagInfo::all() const
{
  std::string out;
  for ( auto const &spelling : spellings )
    out += "[" + spelling + "]";
  return out;
}

std::size_t listTags( Config const &config )
{
  TestSpec testSpec = config.testSpec();
  if ( config.hasTestFilters() )
    Catch::cout() << "Tags for matching test cases:\n";
  else
    {
      Catch::cout() << "All available tags:\n";
    }

  std::map<std::string, TagInfo> tagCounts;

  std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
  for ( auto const &testCase : matchedTestCases )
    {
      for ( auto const &tagName : testCase.getTestCaseInfo().tags )
        {
          std::string lcaseTagName = toLower( tagName );
          auto countIt = tagCounts.find( lcaseTagName );
          if ( countIt == tagCounts.end() )
            countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
          countIt->second.add( tagName );
        }
    }

  for ( auto const &tagCount : tagCounts )
    {
      ReusableStringStream rss;
      rss << "  " << std::setw(2) << tagCount.second.count << "  ";
                                   auto str = rss.str();
                                   auto wrapper = Column( tagCount.second.all() )
                                   .initialIndent( 0 )
                                   .indent( str.size() )
                                   .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );
                                   Catch::cout() << str << wrapper << '\n';
    }
                                                     Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
                                                                    return tagCounts.size();
}

                                                                  std::size_t listReporters( Config const & /*config*/ )
{
  Catch::cout() << "Available reporters:\n";
  IReporterRegistry::FactoryMap const &factories = getRegistryHub().getReporterRegistry().getFactories();
  std::size_t maxNameLen = 0;
  for ( auto const &factoryKvp : factories )
    maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );

  for ( auto const &factoryKvp : factories )
    {
      Catch::cout()
      << Column( factoryKvp.first + ":" )
       .indent(2)
       .width( 5+maxNameLen )
       +  Column( factoryKvp.second->getDescription() )
       .initialIndent(0)
       .indent(2)
       .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )
       << "\n";
    }
   Catch::cout() << std::endl;
   return factories.size();
}

 Option<std::size_t> list( Config const &config )
{
  Option<std::size_t> listedCount;
  if ( config.listTests() )
    listedCount = listedCount.valueOr(0) + listTests( config );
  if ( config.listTestNamesOnly() )
    listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
  if ( config.listTags() )
    listedCount = listedCount.valueOr(0) + listTags( config );
  if ( config.listReporters() )
    listedCount = listedCount.valueOr(0) + listReporters( config );
  return listedCount;
}

      } // end namespace Catch
// end catch_list.cpp
// start catch_matchers.cpp

namespace Catch
{
  namespace Matchers
  {
    namespace Impl
    {

      std::string MatcherUntypedBase::toString() const
{
  if ( m_cachedToString.empty() )
    m_cachedToString = describe();
  return m_cachedToString;
}

MatcherUntypedBase::~MatcherUntypedBase() = default;

    } // namespace Impl
  } // namespace Matchers

using namespace Matchers;
using Matchers::Impl::MatcherBase;

} // namespace Catch
// end catch_matchers.cpp
// start catch_matchers_floating.cpp

// start catch_to_string.hpp

#include <string>

namespace Catch
{
  template <typename T>
  std::string to_string(T const &t)
{
#if defined(CATCH_CONFIG_CPP11_TO_STRING)
  return std::to_string(t);
#else
  ReusableStringStream rss;
  rss << t;
  return rss.str();
#endif
}
           } // end namespace Catch

// end catch_to_string.hpp
#include <cstdlib>
#include <cstdint>
#include <cstring>
#include <stdexcept>

namespace Catch
{
  namespace Matchers
  {
    namespace Floating
    {
      enum class FloatingPointKind : uint8_t
      {
        Float,
        Double
      };
    }
  }
}

namespace
{

  template <typename T>
  struct Converter;

  template <>
  struct Converter<float>
  {
    static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
    Converter(float f)
{
  std::memcpy(&i, &f, sizeof(f));
}
int32_t i;
  };

template <>
struct Converter<double>
{
  static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
  Converter(double d)
{
  std::memcpy(&i, &d, sizeof(d));
}
int64_t i;
};

template <typename T>
auto convert(T t) -> Converter<T>
{
  return Converter<T>(t);
}

template <typename FP>
bool almostEqualUlps(FP lhs, FP rhs, int maxUlpDiff)
{
  // Comparison with NaN should always be false.
  // This way we can rule it out before getting into the ugly details
  if (std::isnan(lhs) || std::isnan(rhs))
    {
      return false;
    }

  auto lc = convert(lhs);
  auto rc = convert(rhs);

  if ((lc.i < 0) != (rc.i < 0))
    {
      // Potentially we can have +0 and -0
      return lhs == rhs;
    }

  auto ulpDiff = std::abs(lc.i - rc.i);
  return ulpDiff <= maxUlpDiff;
}

               }

namespace Catch
{
  namespace Matchers
  {
    namespace Floating
    {
      WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
:m_target { target }, m_margin { margin }
{
  if (m_margin < 0)
    {
      throw std::domain_error("Allowed margin difference has to be >= 0");
    }
}

// Performs equivalent check of std::fabs(lhs - rhs) <= margin
// But without the subtraction to allow for INFINITY in comparison
bool WithinAbsMatcher::match(double const &matchee) const
{
  return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);
}

std::string WithinAbsMatcher::describe() const
{
  return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
}

WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType)
:m_target { target }, m_ulps { ulps }, m_type { baseType }
{
  if (m_ulps < 0)
    {
      throw std::domain_error("Allowed ulp difference has to be >= 0");
    }
}

bool WithinUlpsMatcher::match(double const &matchee) const
{
  switch (m_type)
    {
      case FloatingPointKind::Float:
        return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);
      case FloatingPointKind::Double:
        return almostEqualUlps<double>(matchee, m_target, m_ulps);
      default:
        throw std::domain_error("Unknown FloatingPointKind value");
    }
}

std::string WithinUlpsMatcher::describe() const
{
  return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : "");
}

                      }// namespace Floating

Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff)
{
  return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
}

Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff)
{
  return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
}

Floating::WithinAbsMatcher WithinAbs(double target, double margin)
{
  return Floating::WithinAbsMatcher(target, margin);
}

                                         } // namespace Matchers
                             } // namespace Catch

// end catch_matchers_floating.cpp
// start catch_matchers_generic.cpp

std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string &desc)
{
  if (desc.empty())
    {
      return "matches undescribed predicate";
    }
  else
    {
      return "matches predicate: \"" + desc + '"';
    }
}
// end catch_matchers_generic.cpp
// start catch_matchers_string.cpp

#include <regex>

namespace Catch
{
  namespace Matchers
  {

    namespace StdString
    {

      CasedString::CasedString( std::string const &str, CaseSensitive::Choice caseSensitivity )
      :   m_caseSensitivity( caseSensitivity ),
      m_str( adjustString( str ) )
{}
std::string CasedString::adjustString( std::string const &str ) const
{
  return m_caseSensitivity == CaseSensitive::No
  ? toLower( str )
  : str;
}
std::string CasedString::caseSensitivitySuffix() const
{
  return m_caseSensitivity == CaseSensitive::No
  ? " (case insensitive)"
  : std::string();
}

StringMatcherBase::StringMatcherBase( std::string const &operation, CasedString const &comparator )
: m_comparator( comparator ),
m_operation( operation )
{
}

std::string StringMatcherBase::describe() const
{
  std::string description;
  description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
                      m_comparator.caseSensitivitySuffix().size());
  description += m_operation;
  description += ": \"";
  description += m_comparator.m_str;
  description += "\"";
  description += m_comparator.caseSensitivitySuffix();
  return description;
}

EqualsMatcher::EqualsMatcher( CasedString const &comparator ) : StringMatcherBase( "equals", comparator ) {}

bool EqualsMatcher::match( std::string const &source ) const
{
  return m_comparator.adjustString( source ) == m_comparator.m_str;
}

ContainsMatcher::ContainsMatcher( CasedString const &comparator ) : StringMatcherBase( "contains", comparator ) {}

bool ContainsMatcher::match( std::string const &source ) const
{
  return contains( m_comparator.adjustString( source ), m_comparator.m_str );
}

StartsWithMatcher::StartsWithMatcher( CasedString const &comparator ) : StringMatcherBase( "starts with", comparator ) {}

bool StartsWithMatcher::match( std::string const &source ) const
{
  return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
}

EndsWithMatcher::EndsWithMatcher( CasedString const &comparator ) : StringMatcherBase( "ends with", comparator ) {}

bool EndsWithMatcher::match( std::string const &source ) const
{
  return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
}

RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}

bool RegexMatcher::match(std::string const &matchee) const
{
  auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
  if (m_caseSensitivity == CaseSensitive::Choice::No)
    {
      flags |= std::regex::icase;
    }
  auto reg = std::regex(m_regex, flags);
  return std::regex_match(matchee, reg);
}

std::string RegexMatcher::describe() const
{
  return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively");
}

    } // namespace StdString

StdString::EqualsMatcher Equals( std::string const &str, CaseSensitive::Choice caseSensitivity )
{
  return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
}
StdString::ContainsMatcher Contains( std::string const &str, CaseSensitive::Choice caseSensitivity )
{
  return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
}
StdString::EndsWithMatcher EndsWith( std::string const &str, CaseSensitive::Choice caseSensitivity )
{
  return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
}
StdString::StartsWithMatcher StartsWith( std::string const &str, CaseSensitive::Choice caseSensitivity )
{
  return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
}

StdString::RegexMatcher Matches(std::string const &regex, CaseSensitive::Choice caseSensitivity)
{
  return StdString::RegexMatcher(regex, caseSensitivity);
}

  } // namespace Matchers
} // namespace Catch
// end catch_matchers_string.cpp
// start catch_message.cpp

// start catch_uncaught_exceptions.h

namespace Catch
{
  bool uncaught_exceptions();
} // end namespace Catch

// end catch_uncaught_exceptions.h
namespace Catch
{

  MessageInfo::MessageInfo(   std::string const &_macroName,
                              SourceLineInfo const &_lineInfo,
                              ResultWas::OfType _type )
  :   macroName( _macroName ),
  lineInfo( _lineInfo ),
  type( _type ),
  sequence( ++globalCount )
{}

bool MessageInfo::operator==( MessageInfo const &other ) const
{
  return sequence == other.sequence;
}

bool MessageInfo::operator<( MessageInfo const &other ) const
{
  return sequence < other.sequence;
}

// This may need protecting if threading support is added
unsigned int MessageInfo::globalCount = 0;

////////////////////////////////////////////////////////////////////////////

Catch::MessageBuilder::MessageBuilder( std::string const &macroName,
                                       SourceLineInfo const &lineInfo,
                                       ResultWas::OfType type )
:m_info(macroName, lineInfo, type) {}

////////////////////////////////////////////////////////////////////////////

ScopedMessage::ScopedMessage( MessageBuilder const &builder )
: m_info( builder.m_info )
{
  m_info.message = builder.m_stream.str();
  getResultCapture().pushScopedMessage( m_info );
}

ScopedMessage::~ScopedMessage()
{
  if ( !uncaught_exceptions() )
    {
      getResultCapture().popScopedMessage(m_info);
    }
}
                } // end namespace Catch
// end catch_message.cpp
// start catch_output_redirect.cpp

// start catch_output_redirect.h
#ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
#define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H

#include <cstdio>
#include <iosfwd>
#include <string>

namespace Catch
{

  class RedirectedStream
  {
    std::ostream &m_originalStream;
    std::ostream &m_redirectionStream;
    std::streambuf *m_prevBuf;

    public:
    RedirectedStream( std::ostream &originalStream, std::ostream &redirectionStream );
    ~RedirectedStream();
  };

  class RedirectedStdOut
  {
    ReusableStringStream m_rss;
    RedirectedStream m_cout;
    public:
    RedirectedStdOut();
    auto str() const -> std::string;
  };

  // StdErr has two constituent streams in C++, std::cerr and std::clog
  // This means that we need to redirect 2 streams into 1 to keep proper
  // order of writes
  class RedirectedStdErr
{
  ReusableStringStream m_rss;
  RedirectedStream m_cerr;
  RedirectedStream m_clog;
public:
  RedirectedStdErr();
  auto str() const -> std::string;
};

// Windows's implementation of std::tmpfile is terrible (it tries
// to create a file inside system folder, thus requiring elevated
// privileges for the binary), so we have to use tmpnam(_s) and
// create the file ourselves there.
class TempFile
{
  public:
  TempFile(TempFile const &) = delete;
  TempFile &operator=(TempFile const &) = delete;
  TempFile(TempFile&&) = delete;
  TempFile &operator=(TempFile&&) = delete;

  TempFile();
  ~TempFile();

  std::FILE *getFile();
  std::string getContents();

  private:
  std::FILE *m_file = nullptr;
#if defined(_MSC_VER)
  char m_buffer[L_tmpnam] = { 0 };
#endif
};

class OutputRedirect
{
  public:
  OutputRedirect(OutputRedirect const &) = delete;
  OutputRedirect &operator=(OutputRedirect const &) = delete;
  OutputRedirect(OutputRedirect&&) = delete;
  OutputRedirect &operator=(OutputRedirect&&) = delete;

  OutputRedirect(std::string &stdout_dest, std::string &stderr_dest);
  ~OutputRedirect();

  private:
  int m_originalStdout = -1;
  int m_originalStderr = -1;
  TempFile m_stdoutFile;
  TempFile m_stderrFile;
  std::string &m_stdoutDest;
  std::string &m_stderrDest;
};

} // end namespace Catch

#endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
// end catch_output_redirect.h
#include <cstdio>
#include <cstring>
#include <fstream>
#include <sstream>
#include <stdexcept>

#if defined(_MSC_VER)
#include <io.h>      //_dup and _dup2
#define dup _dup
#define dup2 _dup2
#define fileno _fileno
#else
#include <unistd.h>  // dup and dup2
#endif

namespace Catch
{

  RedirectedStream::RedirectedStream( std::ostream &originalStream, std::ostream &redirectionStream )
  :   m_originalStream( originalStream ),
  m_redirectionStream( redirectionStream ),
  m_prevBuf( m_originalStream.rdbuf() )
{
  m_originalStream.rdbuf( m_redirectionStream.rdbuf() );
}

RedirectedStream::~RedirectedStream()
{
  m_originalStream.rdbuf( m_prevBuf );
}

RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}
auto RedirectedStdOut::str() const -> std::string
{
  return m_rss.str();
}

RedirectedStdErr::RedirectedStdErr()
:   m_cerr( Catch::cerr(), m_rss.get() ),
m_clog( Catch::clog(), m_rss.get() )
{}
auto RedirectedStdErr::str() const -> std::string
{
  return m_rss.str();
}

#if defined(_MSC_VER)
TempFile::TempFile()
{
  if (tmpnam_s(m_buffer))
    {
      throw std::runtime_error("Could not get a temp filename");
    }
  if (fopen_s(&m_file, m_buffer, "w"))
    {
      char buffer[100];
      if (strerror_s(buffer, errno))
        {
          throw std::runtime_error("Could not translate errno to string");
        }
      throw std::runtime_error("Could not open the temp file: " + std::string(m_buffer) + buffer);
    }
}
#else
TempFile::TempFile()
{
  m_file = std::tmpfile();
  if (!m_file)
    {
      throw std::runtime_error("Could not create a temp file.");
    }
}

#endif

TempFile::~TempFile()
{
  // TBD: What to do about errors here?
  std::fclose(m_file);
  // We manually create the file on Windows only, on Linux
  // it will be autodeleted
#if defined(_MSC_VER)
  std::remove(m_buffer);
#endif
}

FILE *TempFile::getFile()
{
  return m_file;
}

std::string TempFile::getContents()
{
  std::stringstream sstr;
  char buffer[100] = {};
  std::rewind(m_file);
  while (std::fgets(buffer, sizeof(buffer), m_file))
    {
      sstr << buffer;
    }
  return sstr.str();
}

OutputRedirect::OutputRedirect(std::string &stdout_dest, std::string &stderr_dest) :
m_originalStdout(dup(1)),
m_originalStderr(dup(2)),
m_stdoutDest(stdout_dest),
m_stderrDest(stderr_dest)
{
  dup2(fileno(m_stdoutFile.getFile()), 1);
  dup2(fileno(m_stderrFile.getFile()), 2);
}

OutputRedirect::~OutputRedirect()
{
  Catch::cout() << std::flush;
  fflush(stdout);
  // Since we support overriding these streams, we flush cerr
  // even though std::cerr is unbuffered
  Catch::cerr() << std::flush;
  Catch::clog() << std::flush;
  fflush(stderr);

  dup2(m_originalStdout, 1);
  dup2(m_originalStderr, 2);

  m_stdoutDest += m_stdoutFile.getContents();
  m_stderrDest += m_stderrFile.getContents();
}

              } // namespace Catch

#if defined(_MSC_VER)
#undef dup
#undef dup2
#undef fileno
#endif
// end catch_output_redirect.cpp
// start catch_random_number_generator.cpp

// start catch_random_number_generator.h

#include <algorithm>

namespace Catch
{

  struct IConfig;

  void seedRng( IConfig const &config );

  unsigned int rngSeed();

  struct RandomNumberGenerator
  {
    using result_type = unsigned int;

    static constexpr result_type (min)()
{
  return 0;
}
static constexpr result_type (max)()
{
  return 1000000;
}

result_type operator()( result_type n ) const;
result_type operator()() const;

template<typename V>
static void shuffle( V &vector )
{
  RandomNumberGenerator rng;
  std::shuffle( vector.begin(), vector.end(), rng );
}
        };

  }

// end catch_random_number_generator.h
#include <cstdlib>

namespace Catch
{

  void seedRng( IConfig const &config )
{
  if ( config.rngSeed() != 0 )
    std::srand( config.rngSeed() );
}
unsigned int rngSeed()
{
  return getCurrentContext().getConfig()->rngSeed();
}

RandomNumberGenerator::result_type RandomNumberGenerator::operator()( result_type n ) const
{
  return std::rand() % n;
}
RandomNumberGenerator::result_type RandomNumberGenerator::operator()() const
{
  return std::rand() % (max)();
}

}
// end catch_random_number_generator.cpp
// start catch_registry_hub.cpp

// start catch_test_case_registry_impl.h

#include <vector>
#include <set>
#include <algorithm>
#include <ios>

namespace Catch
{

  class TestCase;
  struct IConfig;

  std::vector<TestCase> sortTests( IConfig const &config, std::vector<TestCase> const &unsortedTestCases );
  bool matchTest( TestCase const &testCase, TestSpec const &testSpec, IConfig const &config );

  void enforceNoDuplicateTestCases( std::vector<TestCase> const &functions );

  std::vector<TestCase> filterTests( std::vector<TestCase> const &testCases, TestSpec const &testSpec, IConfig const &config );
  std::vector<TestCase> const &getAllTestCasesSorted( IConfig const &config );

  class TestRegistry : public ITestCaseRegistry
  {
    public:
    virtual ~TestRegistry() = default;

    virtual void registerTest( TestCase const &testCase );

    std::vector<TestCase> const &getAllTests() const override;
    std::vector<TestCase> const &getAllTestsSorted( IConfig const &config ) const override;

    private:
    std::vector<TestCase> m_functions;
    mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;
    mutable std::vector<TestCase> m_sortedFunctions;
    std::size_t m_unnamedCount = 0;
    std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
                       };

  ///////////////////////////////////////////////////////////////////////////

  class TestInvokerAsFunction : public ITestInvoker
  {
    void(*m_testAsFunction)();
    public:
    TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;

    void invoke() const override;
  };

  std::string extractClassName( StringRef const &classOrQualifiedMethodName );

  ///////////////////////////////////////////////////////////////////////////

               } // end namespace Catch

// end catch_test_case_registry_impl.h
// start catch_reporter_registry.h

#include <map>

namespace Catch
{

  class ReporterRegistry : public IReporterRegistry
  {

    public:

    ~ReporterRegistry() override;

    IStreamingReporterPtr create( std::string const &name, IConfigPtr const &config ) const override;

    void registerReporter( std::string const &name, IReporterFactoryPtr const &factory );
    void registerListener( IReporterFactoryPtr const &factory );

    FactoryMap const &getFactories() const override;
    Listeners const &getListeners() const override;

    private:
    FactoryMap m_factories;
    Listeners m_listeners;
  };
}

// end catch_reporter_registry.h
// start catch_tag_alias_registry.h

// start catch_tag_alias.h

#include <string>

namespace Catch
{

  struct TagAlias
  {
    TagAlias(std::string const &_tag, SourceLineInfo _lineInfo);

    std::string tag;
    SourceLineInfo lineInfo;
  };

} // end namespace Catch

// end catch_tag_alias.h
#include <map>

namespace Catch
{

  class TagAliasRegistry : public ITagAliasRegistry
  {
    public:
    ~TagAliasRegistry() override;
    TagAlias const *find( std::string const &alias ) const override;
    std::string expandAliases( std::string const &unexpandedTestSpec ) const override;
    void add( std::string const &alias, std::string const &tag, SourceLineInfo const &lineInfo );

    private:
    std::map<std::string, TagAlias> m_registry;
            };

  } // end namespace Catch

// end catch_tag_alias_registry.h
// start catch_startup_exception_registry.h

#include <vector>
#include <exception>

namespace Catch
{

  class StartupExceptionRegistry
  {
    public:
    void add(std::exception_ptr const &exception) noexcept;
    std::vector<std::exception_ptr> const &getExceptions() const noexcept;
    private:
    std::vector<std::exception_ptr> m_exceptions;
               };

               } // end namespace Catch

// end catch_startup_exception_registry.h
namespace Catch
{

  namespace
  {

    class RegistryHub : public IRegistryHub, public IMutableRegistryHub,
    private NonCopyable
    {

      public: // IRegistryHub
      RegistryHub() = default;
      IReporterRegistry const &getReporterRegistry() const override
  {
    return m_reporterRegistry;
  }
  ITestCaseRegistry const &getTestCaseRegistry() const override
  {
    return m_testCaseRegistry;
  }
  IExceptionTranslatorRegistry &getExceptionTranslatorRegistry() override
  {
    return m_exceptionTranslatorRegistry;
  }
  ITagAliasRegistry const &getTagAliasRegistry() const override
  {
    return m_tagAliasRegistry;
  }
  StartupExceptionRegistry const &getStartupExceptionRegistry() const override
  {
    return m_exceptionRegistry;
  }

  public: // IMutableRegistryHub
  void registerReporter( std::string const &name, IReporterFactoryPtr const &factory ) override
  {
    m_reporterRegistry.registerReporter( name, factory );
  }
  void registerListener( IReporterFactoryPtr const &factory ) override
  {
    m_reporterRegistry.registerListener( factory );
  }
  void registerTest( TestCase const &testInfo ) override
  {
    m_testCaseRegistry.registerTest( testInfo );
  }
  void registerTranslator( const IExceptionTranslator *translator ) override
  {
    m_exceptionTranslatorRegistry.registerTranslator( translator );
  }
  void registerTagAlias( std::string const &alias, std::string const &tag, SourceLineInfo const &lineInfo ) override
  {
    m_tagAliasRegistry.add( alias, tag, lineInfo );
  }
  void registerStartupException() noexcept override
  {
    m_exceptionRegistry.add(std::current_exception());
  }

  private:
  TestRegistry m_testCaseRegistry;
  ReporterRegistry m_reporterRegistry;
  ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
  TagAliasRegistry m_tagAliasRegistry;
  StartupExceptionRegistry m_exceptionRegistry;
    };

  // Single, global, instance
  RegistryHub *&getTheRegistryHub()
  {
    static RegistryHub *theRegistryHub = nullptr;
    if ( !theRegistryHub )
      theRegistryHub = new RegistryHub();
    return theRegistryHub;
  }
  }

  IRegistryHub &getRegistryHub()
  {
    return *getTheRegistryHub();
  }
  IMutableRegistryHub &getMutableRegistryHub()
  {
    return *getTheRegistryHub();
  }
  void cleanUp()
  {
    delete getTheRegistryHub();
    getTheRegistryHub() = nullptr;
    cleanUpContext();
    ReusableStringStream::cleanup();
  }
  std::string translateActiveException()
  {
    return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
  }

} // end namespace Catch
// end catch_registry_hub.cpp
// start catch_reporter_registry.cpp

namespace Catch
{

  ReporterRegistry::~ReporterRegistry() = default;

  IStreamingReporterPtr ReporterRegistry::create( std::string const &name, IConfigPtr const &config ) const
{
  auto it =  m_factories.find( name );
  if ( it == m_factories.end() )
    return nullptr;
  return it->second->create( ReporterConfig( config ) );
}

void ReporterRegistry::registerReporter( std::string const &name, IReporterFactoryPtr const &factory )
{
  m_factories.emplace(name, factory);
}
void ReporterRegistry::registerListener( IReporterFactoryPtr const &factory )
{
  m_listeners.push_back( factory );
}

IReporterRegistry::FactoryMap const &ReporterRegistry::getFactories() const
{
  return m_factories;
}
IReporterRegistry::Listeners const &ReporterRegistry::getListeners() const
{
  return m_listeners;
}

}
// end catch_reporter_registry.cpp
// start catch_result_type.cpp

namespace Catch
{

  bool isOk( ResultWas::OfType resultType )
{
  return ( resultType & ResultWas::FailureBit ) == 0;
}
bool isJustInfo( int flags )
{
  return flags == ResultWas::Info;
}

ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs )
{
  return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
}

bool shouldContinueOnFailure( int flags )
{
  return ( flags & ResultDisposition::ContinueOnFailure ) != 0;
}
bool shouldSuppressFailure( int flags )
{
  return ( flags & ResultDisposition::SuppressFail ) != 0;
}

                                                         } // end namespace Catch
// end catch_result_type.cpp
// start catch_run_context.cpp

#include <cassert>
#include <algorithm>
#include <sstream>

namespace Catch
{

  RunContext::RunContext(IConfigPtr const &_config, IStreamingReporterPtr &&reporter)
  :   m_runInfo(_config->name()),
  m_context(getCurrentMutableContext()),
  m_config(_config),
  m_reporter(std::move(reporter)),
  m_lastAssertionInfo { StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
  m_includeSuccessfulResults( m_config->includeSuccessfulResults() )
{
  m_context.setRunner(this);
  m_context.setConfig(m_config);
  m_context.setResultCapture(this);
  m_reporter->testRunStarting(m_runInfo);
}

RunContext::~RunContext()
{
  m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
}

void RunContext::testGroupStarting(std::string const &testSpec, std::size_t groupIndex, std::size_t groupsCount)
{
  m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
}

void RunContext::testGroupEnded(std::string const &testSpec, Totals const &totals, std::size_t groupIndex, std::size_t groupsCount)
{
  m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
}

Totals RunContext::runTest(TestCase const &testCase)
{
  Totals prevTotals = m_totals;

  std::string redirectedCout;
  std::string redirectedCerr;

  auto const &testInfo = testCase.getTestCaseInfo();

  m_reporter->testCaseStarting(testInfo);

  m_activeTestCase = &testCase;

  ITracker &rootTracker = m_trackerContext.startRun();
  assert(rootTracker.isSectionTracker());
  static_cast<SectionTracker &>(rootTracker).addInitialFilters(m_config->getSectionsToRun());
  do
    {
      m_trackerContext.startCycle();
      m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));
      runCurrentTest(redirectedCout, redirectedCerr);
    }
  while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());

  Totals deltaTotals = m_totals.delta(prevTotals);
  if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0)
    {
      deltaTotals.assertions.failed++;
      deltaTotals.testCases.passed--;
      deltaTotals.testCases.failed++;
    }
  m_totals.testCases += deltaTotals.testCases;
  m_reporter->testCaseEnded(TestCaseStats(testInfo,
                                          deltaTotals,
                                          redirectedCout,
                                          redirectedCerr,
                                          aborting()));

  m_activeTestCase = nullptr;
  m_testCaseTracker = nullptr;

  return deltaTotals;
}

IConfigPtr RunContext::config() const
{
  return m_config;
}

IStreamingReporter &RunContext::reporter() const
{
  return *m_reporter;
}

void RunContext::assertionEnded(AssertionResult const &result)
{
  if (result.getResultType() == ResultWas::Ok)
    {
      m_totals.assertions.passed++;
      m_lastAssertionPassed = true;
    }
  else if (!result.isOk())
    {
      m_lastAssertionPassed = false;
      if ( m_activeTestCase->getTestCaseInfo().okToFail() )
        m_totals.assertions.failedButOk++;
      else
        m_totals.assertions.failed++;
    }
  else
    {
      m_lastAssertionPassed = true;
    }

  // We have no use for the return value (whether messages should be cleared), because messages were made scoped
  // and should be let to clear themselves out.
  static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));

  // Reset working state
  resetAssertionInfo();
  m_lastResult = result;
}
void RunContext::resetAssertionInfo()
{
  m_lastAssertionInfo.macroName = StringRef();
  m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
}

bool RunContext::sectionStarted(SectionInfo const &sectionInfo, Counts &assertions)
{
  ITracker &sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));
  if (!sectionTracker.isOpen())
    return false;
  m_activeSections.push_back(&sectionTracker);

  m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;

  m_reporter->sectionStarting(sectionInfo);

  assertions = m_totals.assertions;

  return true;
}

bool RunContext::testForMissingAssertions(Counts &assertions)
{
  if (assertions.total() != 0)
    return false;
  if (!m_config->warnAboutMissingAssertions())
    return false;
  if (m_trackerContext.currentTracker().hasChildren())
    return false;
  m_totals.assertions.failed++;
  assertions.failed++;
  return true;
}

void RunContext::sectionEnded(SectionEndInfo const &endInfo)
{
  Counts assertions = m_totals.assertions - endInfo.prevAssertions;
  bool missingAssertions = testForMissingAssertions(assertions);

  if (!m_activeSections.empty())
    {
      m_activeSections.back()->close();
      m_activeSections.pop_back();
    }

  m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
  m_messages.clear();
}

void RunContext::sectionEndedEarly(SectionEndInfo const &endInfo)
{
  if (m_unfinishedSections.empty())
    m_activeSections.back()->fail();
  else
    m_activeSections.back()->close();
  m_activeSections.pop_back();

  m_unfinishedSections.push_back(endInfo);
}
void RunContext::benchmarkStarting( BenchmarkInfo const &info )
{
  m_reporter->benchmarkStarting( info );
}
void RunContext::benchmarkEnded( BenchmarkStats const &stats )
{
  m_reporter->benchmarkEnded( stats );
}

void RunContext::pushScopedMessage(MessageInfo const &message)
{
  m_messages.push_back(message);
}

void RunContext::popScopedMessage(MessageInfo const &message)
{
  m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
}

std::string RunContext::getCurrentTestName() const
{
  return m_activeTestCase
  ? m_activeTestCase->getTestCaseInfo().name
  : std::string();
}

const AssertionResult *RunContext::getLastResult() const
{
  return &(*m_lastResult);
}

void RunContext::exceptionEarlyReported()
{
  m_shouldReportUnexpected = false;
}

void RunContext::handleFatalErrorCondition( StringRef message )
{
  // First notify reporter that bad things happened
  m_reporter->fatalErrorEncountered(message);

  // Don't rebuild the result -- the stringification itself can cause more fatal errors
  // Instead, fake a result data.
  AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
  tempResult.message = message;
  AssertionResult result(m_lastAssertionInfo, tempResult);

  assertionEnded(result);

  handleUnfinishedSections();

  // Recreate section for test case (as we will lose the one that was in scope)
  auto const &testCaseInfo = m_activeTestCase->getTestCaseInfo();
  SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);

  Counts assertions;
  assertions.failed = 1;
  SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);
  m_reporter->sectionEnded(testCaseSectionStats);

  auto const &testInfo = m_activeTestCase->getTestCaseInfo();

  Totals deltaTotals;
  deltaTotals.testCases.failed = 1;
  deltaTotals.assertions.failed = 1;
  m_reporter->testCaseEnded(TestCaseStats(testInfo,
                                          deltaTotals,
                                          std::string(),
                                          std::string(),
                                          false));
  m_totals.testCases.failed++;
  testGroupEnded(std::string(), m_totals, 1, 1);
  m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
}

bool RunContext::lastAssertionPassed()
{
  return m_lastAssertionPassed;
}

void RunContext::assertionPassed()
{
  m_lastAssertionPassed = true;
  ++m_totals.assertions.passed;
  resetAssertionInfo();
}

bool RunContext::aborting() const
{
  return m_totals.assertions.failed == static_cast<std::size_t>(m_config->abortAfter());
}

void RunContext::runCurrentTest(std::string &redirectedCout, std::string &redirectedCerr)
{
  auto const &testCaseInfo = m_activeTestCase->getTestCaseInfo();
  SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
  m_reporter->sectionStarting(testCaseSection);
  Counts prevAssertions = m_totals.assertions;
  double duration = 0;
  m_shouldReportUnexpected = true;
  m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };

  seedRng(*m_config);

  Timer timer;
  try
    {
      if (m_reporter->getPreferences().shouldRedirectStdOut)
        {
#if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
          RedirectedStdOut redirectedStdOut;
          RedirectedStdErr redirectedStdErr;

          timer.start();
          invokeActiveTestCase();
          redirectedCout += redirectedStdOut.str();
          redirectedCerr += redirectedStdErr.str();
#else
          OutputRedirect r(redirectedCout, redirectedCerr);
          timer.start();
          invokeActiveTestCase();
#endif
        }
      else
        {
          timer.start();
          invokeActiveTestCase();
        }
      duration = timer.getElapsedSeconds();
    }
  catch (TestFailureException &)
    {
      // This just means the test was aborted due to failure
    }
  catch (...)
    {
      // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
      // are reported without translation at the point of origin.
      if ( m_shouldReportUnexpected )
        {
          AssertionReaction dummyReaction;
          handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );
        }
    }
  Counts assertions = m_totals.assertions - prevAssertions;
  bool missingAssertions = testForMissingAssertions(assertions);

  m_testCaseTracker->close();
  handleUnfinishedSections();
  m_messages.clear();

  SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
  m_reporter->sectionEnded(testCaseSectionStats);
}

void RunContext::invokeActiveTestCase()
{
  FatalConditionHandler fatalConditionHandler; // Handle signals
  m_activeTestCase->invoke();
  fatalConditionHandler.reset();
}

void RunContext::handleUnfinishedSections()
{
  // If sections ended prematurely due to an exception we stored their
  // infos here so we can tear them down outside the unwind process.
  for (auto it = m_unfinishedSections.rbegin(),
       itEnd = m_unfinishedSections.rend();
       it != itEnd;
       ++it)
    sectionEnded(*it);
  m_unfinishedSections.clear();
}

void RunContext::handleExpr(
  AssertionInfo const &info,
  ITransientExpression const &expr,
  AssertionReaction &reaction
)
{
  m_reporter->assertionStarting( info );

  bool negated = isFalseTest( info.resultDisposition );
  bool result = expr.getResult() != negated;

  if ( result )
    {
      if (!m_includeSuccessfulResults)
        {
          assertionPassed();
        }
      else
        {
          reportExpr(info, ResultWas::Ok, &expr, negated);
        }
    }
  else
    {
      reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );
      populateReaction( reaction );
    }
}
void RunContext::reportExpr(
  AssertionInfo const &info,
  ResultWas::OfType resultType,
  ITransientExpression const *expr,
  bool negated )
{

  m_lastAssertionInfo = info;
  AssertionResultData data( resultType, LazyExpression( negated ) );

  AssertionResult assertionResult { info, data };
  assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;

  assertionEnded( assertionResult );
}

void RunContext::handleMessage(
  AssertionInfo const &info,
  ResultWas::OfType resultType,
  StringRef const &message,
  AssertionReaction &reaction
)
{
  m_reporter->assertionStarting( info );

  m_lastAssertionInfo = info;

  AssertionResultData data( resultType, LazyExpression( false ) );
  data.message = message;
  AssertionResult assertionResult { m_lastAssertionInfo, data };
  assertionEnded( assertionResult );
  if ( !assertionResult.isOk() )
    populateReaction( reaction );
}
void RunContext::handleUnexpectedExceptionNotThrown(
  AssertionInfo const &info,
  AssertionReaction &reaction
)
{
  handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);
}

void RunContext::handleUnexpectedInflightException(
  AssertionInfo const &info,
  std::string const &message,
  AssertionReaction &reaction
)
{
  m_lastAssertionInfo = info;

  AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
  data.message = message;
  AssertionResult assertionResult { info, data };
  assertionEnded( assertionResult );
  populateReaction( reaction );
}

void RunContext::populateReaction( AssertionReaction &reaction )
{
  reaction.shouldDebugBreak = m_config->shouldDebugBreak();
  reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);
}

void RunContext::handleIncomplete(
  AssertionInfo const &info
)
{
  m_lastAssertionInfo = info;

  AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
  data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
  AssertionResult assertionResult { info, data };
  assertionEnded( assertionResult );
}
void RunContext::handleNonExpr(
  AssertionInfo const &info,
  ResultWas::OfType resultType,
  AssertionReaction &reaction
)
{
  m_lastAssertionInfo = info;

  AssertionResultData data( resultType, LazyExpression( false ) );
  AssertionResult assertionResult { info, data };
  assertionEnded( assertionResult );

  if ( !assertionResult.isOk() )
    populateReaction( reaction );
}

IResultCapture &getResultCapture()
{
  if (auto *capture = getCurrentContext().getResultCapture())
    return *capture;
  else
    CATCH_INTERNAL_ERROR("No result capture instance");
}
                                                }
// end catch_run_context.cpp
// start catch_section.cpp

namespace Catch
{

  Section::Section( SectionInfo const &info )
  :   m_info( info ),
  m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
{
  m_timer.start();
}

Section::~Section()
{
  if ( m_sectionIncluded )
    {
      SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
      if ( uncaught_exceptions() )
        getResultCapture().sectionEndedEarly( endInfo );
      else
        getResultCapture().sectionEnded( endInfo );
    }
}

// This indicates whether the section should be executed or not
Section::operator bool() const
{
  return m_sectionIncluded;
}

} // end namespace Catch
// end catch_section.cpp
// start catch_section_info.cpp

namespace Catch
{

  SectionInfo::SectionInfo
  (   SourceLineInfo const &_lineInfo,
      std::string const &_name,
      std::string const &_description )
  :   name( _name ),
  description( _description ),
  lineInfo( _lineInfo )
{}

SectionEndInfo::SectionEndInfo( SectionInfo const &_sectionInfo, Counts const &_prevAssertions, double _durationInSeconds )
: sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
{}

} // end namespace Catch
// end catch_section_info.cpp
// start catch_session.cpp

// start catch_session.h

#include <memory>

namespace Catch
{

  class Session : NonCopyable
  {
    public:

    Session();
    ~Session() override;

    void showHelp() const;
    void libIdentify();

    int applyCommandLine( int argc, char const *const *argv );

    void useConfigData( ConfigData const &configData );

    int run( int argc, char *argv[] );
#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
    int run( int argc, wchar_t *const argv[] );
#endif
    int run();

    clara::Parser const &cli() const;
    void cli( clara::Parser const &newParser );
    ConfigData &configData();
    Config &config();
    private:
    int runInternal();

    clara::Parser m_cli;
    ConfigData m_configData;
    std::shared_ptr<Config> m_config;
    bool m_startupExceptions = false;
                   };

  } // end namespace Catch

// end catch_session.h
// start catch_version.h

#include <iosfwd>

namespace Catch
{

  // Versioning information
  struct Version
  {
    Version( Version const &) = delete;
    Version &operator=( Version const &) = delete;
    Version(    unsigned int _majorVersion,
                unsigned int _minorVersion,
                unsigned int _patchNumber,
                char const *const _branchName,
                unsigned int _buildNumber );

    unsigned int const majorVersion;
    unsigned int const minorVersion;
    unsigned int const patchNumber;

    // buildNumber is only used if branchName is not null
    char const *const branchName;
    unsigned int const buildNumber;

    friend std::ostream &operator << ( std::ostream &os, Version const &version );
                                  };

    Version const &libraryVersion();
  }

// end catch_version.h
#include <cstdlib>
#include <iomanip>

  namespace Catch
  {

    namespace
    {
      const int MaxExitCode = 255;

      IStreamingReporterPtr createReporter(std::string const &reporterName, IConfigPtr const &config)
{
  auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);
  CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'");

                return reporter;
}

              IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const &config)
{
  if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty())
    {
      return createReporter(config->getReporterName(), config);
    }

  auto multi = std::unique_ptr<ListeningReporter>(new ListeningReporter);

  auto const &listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();
  for (auto const &listener : listeners)
    {
      multi->addListener(listener->create(Catch::ReporterConfig(config)));
    }
  multi->addReporter(createReporter(config->getReporterName(), config));
  return std::move(multi);
}

Catch::Totals runTests(std::shared_ptr<Config> const &config)
{
  // FixMe: Add listeners in order first, then add reporters.

  auto reporter = makeReporter(config);

  RunContext context(config, std::move(reporter));

  Totals totals;

  context.testGroupStarting(config->name(), 1, 1);

  TestSpec testSpec = config->testSpec();

  auto const &allTestCases = getAllTestCasesSorted(*config);
  for (auto const &testCase : allTestCases)
    {
      if (!context.aborting() && matchTest(testCase, testSpec, *config))
        totals += context.runTest(testCase);
      else
        context.reporter().skipTest(testCase);
    }

  if (config->warnAboutNoTests() && totals.testCases.total() == 0)
    {
      ReusableStringStream testConfig;

      bool first = true;
      for (const auto &input : config->getTestsOrTags())
        {
          if (!first)
            {
              testConfig << ' ';
            }
          first = false;
          testConfig << input;
        }

      context.reporter().noMatchingTestCases(testConfig.str());
      totals.error = -1;
    }

  context.testGroupEnded(config->name(), totals, 1, 1);
  return totals;
}

void applyFilenamesAsTags(Catch::IConfig const &config)
{
  auto &tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
  for (auto &testCase : tests)
    {
      auto tags = testCase.tags;

      std::string filename = testCase.lineInfo.file;
      auto lastSlash = filename.find_last_of("\\/");
      if (lastSlash != std::string::npos)
        {
          filename.erase(0, lastSlash);
          filename[0] = '#';
        }

      auto lastDot = filename.find_last_of('.');
      if (lastDot != std::string::npos)
        {
          filename.erase(lastDot);
        }

      tags.push_back(std::move(filename));
      setTags(testCase, tags);
    }
}

                                    } // anon namespace

Session::Session()
{
  static bool alreadyInstantiated = false;
  if ( alreadyInstantiated )
    {
      try
        {
          CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" );
        }
      catch (...)
        {
          getMutableRegistryHub().registerStartupException();
        }
    }

  const auto &exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
  if ( !exceptions.empty() )
    {
      m_startupExceptions = true;
      Colour colourGuard( Colour::Red );
      Catch::cerr() << "Errors occurred during startup!" << '\n';
                     // iterate over all exceptions and notify user
                     for ( const auto &ex_ptr : exceptions )
        {
          try
            {
              std::rethrow_exception(ex_ptr);
            }
          catch ( std::exception const &ex )
            {
              Catch::cerr() << Column( ex.what() ).indent(2) << '\n';
            }
        }
    }

  alreadyInstantiated = true;
  m_cli = makeCommandLineParser( m_configData );
}
Session::~Session()
{
  Catch::cleanUp();
}

void Session::showHelp() const
{
  Catch::cout()
  << "\nCatch v" << libraryVersion() << "\n"
                                      << m_cli << std::endl
                                                << "For more detailed usage please see the project docs\n" << std::endl;
}
                                               void Session::libIdentify()
{
  Catch::cout()
  << std::left << std::setw(16) << "description: " << "A Catch test executable\n"
                                                    << std::left << std::setw(16) << "category: " << "testframework\n"
                                                                  << std::left << std::setw(16) << "framework: " << "Catch Test\n"
                                                                                << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
}

                                                                                  int Session::applyCommandLine( int argc, char const *const *argv )
{
  if ( m_startupExceptions )
    return 1;

  auto result = m_cli.parse( clara::Args( argc, argv ) );
  if ( !result )
    {
      Catch::cerr()
      << Colour( Colour::Red )
       << "\nError(s) in input:\n"
        << Column( result.errorMessage() ).indent( 2 )
         << "\n\n";
         Catch::cerr() << "Run with -? for usage\n" << std::endl;
                        return MaxExitCode;
    }

                    if ( m_configData.showHelp )
                      showHelp();
     if ( m_configData.libIdentify )
       libIdentify();
     m_config.reset();
     return 0;
}

   void Session::useConfigData( ConfigData const &configData )
{
  m_configData = configData;
  m_config.reset();
}

int Session::run( int argc, char *argv[] )
{
  if ( m_startupExceptions )
    return 1;
  int returnCode = applyCommandLine( argc, argv );
  if ( returnCode == 0 )
    returnCode = run();
  return returnCode;
}

#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
int Session::run( int argc, wchar_t *const argv[] )
{

  char **utf8Argv = new char *[ argc ];

  for ( int i = 0; i < argc; ++i )
    {
      int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );

      utf8Argv[ i ] = new char[ bufSize ];

      WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
    }

  int returnCode = run( argc, utf8Argv );

  for ( int i = 0; i < argc; ++i )
          delete [] utf8Argv[ i ];

  delete [] utf8Argv;

  return returnCode;
}
#endif
int Session::run()
{
  if ( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 )
    {
      Catch::cout() << "...waiting for enter/ return before starting" << std::endl;
                     static_cast<void>(std::getchar());
    }
                 int exitCode = runInternal();
  if ( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 )
    {
      Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl;
                                                                                   static_cast<void>(std::getchar());
    }
                                                                               return exitCode;
}

               clara::Parser const &Session::cli() const
{
  return m_cli;
}
void Session::cli( clara::Parser const &newParser )
{
  m_cli = newParser;
}
ConfigData &Session::configData()
{
  return m_configData;
}
Config &Session::config()
{
  if ( !m_config )
    m_config = std::make_shared<Config>( m_configData );
  return *m_config;
}

int Session::runInternal()
{
  if ( m_startupExceptions )
    return 1;

  if ( m_configData.showHelp || m_configData.libIdentify )
    return 0;

  try
    {
      config(); // Force config to be constructed

      seedRng( *m_config );

      if ( m_configData.filenamesAsTags )
        applyFilenamesAsTags( *m_config );

      // Handle list request
      if ( Option<std::size_t> listed = list( config() ) )
        return static_cast<int>( *listed );

      auto totals = runTests( m_config );
      // Note that on unices only the lower 8 bits are usually used, clamping
      // the return value to 255 prevents false negative when some multiple
      // of 256 tests has failed
      return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
    }
  catch ( std::exception &ex )
    {
      Catch::cerr() << ex.what() << std::endl;
                     return MaxExitCode;
    }
}

                           } // end namespace Catch
// end catch_session.cpp
// start catch_startup_exception_registry.cpp

namespace Catch
{
  void StartupExceptionRegistry::add( std::exception_ptr const &exception ) noexcept
{
  try {
      m_exceptions.push_back(exception);
    }
  catch (...)
    {
      // If we run out of memory during start-up there's really not a lot more we can do about it
      std::terminate();
    }
}

std::vector<std::exception_ptr> const &StartupExceptionRegistry::getExceptions() const noexcept
{
  return m_exceptions;
}

           } // end namespace Catch
// end catch_startup_exception_registry.cpp
// start catch_stream.cpp

#include <cstdio>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <memory>

#if defined(__clang__)
#    pragma clang diagnostic push
#    pragma clang diagnostic ignored "-Wexit-time-destructors"
#endif

namespace Catch
{

  Catch::IStream::~IStream() = default;

  namespace detail
  {
    namespace
    {
      template<typename WriterF, std::size_t bufferSize=256>
      class StreamBufImpl : public std::streambuf
      {
        char data[bufferSize];
        WriterF m_writer;

        public:
        StreamBufImpl()
{
  setp( data, data + sizeof(data) );
}

~StreamBufImpl() noexcept
{
  StreamBufImpl::sync();
}

private:
int overflow( int c ) override
{
  sync();

  if ( c != EOF )
    {
      if ( pbase() == epptr() )
        m_writer( std::string( 1, static_cast<char>( c ) ) );
      else
        sputc( static_cast<char>( c ) );
    }
  return 0;
}

int sync() override
{
  if ( pbase() != pptr() )
    {
      m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
      setp( pbase(), epptr() );
    }
  return 0;
}
        };

///////////////////////////////////////////////////////////////////////////

struct OutputDebugWriter
{

  void operator()( std::string const &str )
{
  writeToDebugConsole( str );
}
};

///////////////////////////////////////////////////////////////////////////

class FileStream : public IStream
{
  mutable std::ofstream m_ofs;
  public:
  FileStream( StringRef filename )
{
  m_ofs.open( filename.c_str() );
  CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" );
}
               ~FileStream() override = default;
               public: // IStream
               std::ostream &stream() const override
{
  return m_ofs;
}
                                                       };

///////////////////////////////////////////////////////////////////////////

class CoutStream : public IStream
{
  mutable std::ostream m_os;
  public:
  // Store the streambuf from cout up-front because
  // cout may get redirected when running tests
CoutStream() : m_os( Catch::cout().rdbuf() ) {}
~CoutStream() override = default;

public: // IStream
std::ostream &stream() const override
{
  return m_os;
}
};

///////////////////////////////////////////////////////////////////////////

class DebugOutStream : public IStream
{
  std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;
  mutable std::ostream m_os;
  public:
  DebugOutStream()
  :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
  m_os( m_streamBuf.get() )
{}

~DebugOutStream() override = default;

public: // IStream
std::ostream &stream() const override
{
  return m_os;
}
                 };

                               }
                 } // namespace anon::detail

///////////////////////////////////////////////////////////////////////////

auto makeStream( StringRef const &filename ) -> IStream const *
{
  if ( filename.empty() )
    return new detail::CoutStream();
  else if ( filename[0] == '%' )
    {
      if ( filename == "%debug" )
        return new detail::DebugOutStream();
      else
        CATCH_ERROR( "Unrecognised stream: '" << filename << "'" );
    }
               else
                 return new detail::FileStream( filename );
}

// This class encapsulates the idea of a pool of ostringstreams that can be reused.
struct StringStreams
{
  std::vector<std::unique_ptr<std::ostringstream>> m_streams;
  std::vector<std::size_t> m_unused;
  std::ostringstream m_referenceStream; // Used for copy state/ flags from
  static StringStreams *s_instance;

  auto add() -> std::size_t
{
  if ( m_unused.empty() )
    {
      m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );
      return m_streams.size()-1;
    }
  else {
      auto index = m_unused.back();
      m_unused.pop_back();
      return index;
    }
}

void release( std::size_t index )
{
  m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
  m_unused.push_back(index);
}

// !TBD: put in TLS
static auto instance() -> StringStreams &
{
  if ( !s_instance )
    s_instance = new StringStreams();
  return *s_instance;
}
static void cleanup()
{
  delete s_instance;
  s_instance = nullptr;
}
                   };

StringStreams *StringStreams::s_instance = nullptr;

void ReusableStringStream::cleanup()
{
  StringStreams::cleanup();
}

ReusableStringStream::ReusableStringStream()
:   m_index( StringStreams::instance().add() ),
m_oss( StringStreams::instance().m_streams[m_index].get() )
{}

ReusableStringStream::~ReusableStringStream()
{
  static_cast<std::ostringstream *>( m_oss )->str("");
  m_oss->clear();
  StringStreams::instance().release( m_index );
}

auto ReusableStringStream::str() const -> std::string
{
  return static_cast<std::ostringstream *>( m_oss )->str();
}

///////////////////////////////////////////////////////////////////////////

#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
std::ostream &cout()
{
  return std::cout;
}
std::ostream &cerr()
{
  return std::cerr;
}
std::ostream &clog()
{
  return std::clog;
}
#endif
                  }

#if defined(__clang__)
#    pragma clang diagnostic pop
#endif
// end catch_stream.cpp
// start catch_string_manip.cpp

#include <algorithm>
#include <ostream>
#include <cstring>
#include <cctype>

namespace Catch
{

  bool startsWith( std::string const &s, std::string const &prefix )
{
  return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
}
bool startsWith( std::string const &s, char prefix )
{
  return !s.empty() && s[0] == prefix;
}
bool endsWith( std::string const &s, std::string const &suffix )
{
  return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
}
bool endsWith( std::string const &s, char suffix )
{
  return !s.empty() && s[s.size()-1] == suffix;
}
bool contains( std::string const &s, std::string const &infix )
{
  return s.find( infix ) != std::string::npos;
}
char toLowerCh(char c)
{
  return static_cast<char>( std::tolower( c ) );
}
void toLowerInPlace( std::string &s )
{
  std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
}
std::string toLower( std::string const &s )
{
  std::string lc = s;
  toLowerInPlace( lc );
  return lc;
}
std::string trim( std::string const &str )
{
  static char const *whitespaceChars = "\n\r\t ";
  std::string::size_type start = str.find_first_not_of( whitespaceChars );
  std::string::size_type end = str.find_last_not_of( whitespaceChars );

  return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
}

bool replaceInPlace( std::string &str, std::string const &replaceThis, std::string const &withThis )
{
  bool replaced = false;
  std::size_t i = str.find( replaceThis );
  while ( i != std::string::npos )
    {
      replaced = true;
      str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
      if ( i < str.size()-withThis.size() )
             i = str.find( replaceThis, i+withThis.size() );
      else
        i = std::string::npos;
    }
  return replaced;
}

pluralise::pluralise( std::size_t count, std::string const &label )
:   m_count( count ),
m_label( label )
{}

std::ostream &operator << ( std::ostream &os, pluralise const &pluraliser )
{
  os << pluraliser.m_count << ' ' << pluraliser.m_label;
                            if ( pluraliser.m_count != 1 )
                              os << 's';
                            return os;
}

                             }
// end catch_string_manip.cpp
// start catch_stringref.cpp

#if defined(__clang__)
#    pragma clang diagnostic push
#    pragma clang diagnostic ignored "-Wexit-time-destructors"
#endif

#include <ostream>
#include <cstring>
#include <cstdint>

                          namespace
                          {
                            const uint32_t byte_2_lead = 0xC0;
                            const uint32_t byte_3_lead = 0xE0;
                            const uint32_t byte_4_lead = 0xF0;
                          }

                          namespace Catch
                          {
                            StringRef::StringRef( char const *rawChars ) noexcept
                            :
                            StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
{}

StringRef::operator std::string() const
{
  return std::string( m_start, m_size );
}

void StringRef::swap( StringRef &other ) noexcept
{
  std::swap( m_start, other.m_start );
  std::swap( m_size, other.m_size );
  std::swap( m_data, other.m_data );
}

auto StringRef::c_str() const -> char const *
{
  if ( isSubstring() )
    const_cast<StringRef *>( this )->takeOwnership();
  return m_start;
}
auto StringRef::currentData() const noexcept -> char const *
{
  return m_start;
}

auto StringRef::isOwned() const noexcept -> bool
{
  return m_data != nullptr;
}
auto StringRef::isSubstring() const noexcept -> bool
{
  return m_start[m_size] != '\0';
}

void StringRef::takeOwnership()
{
  if ( !isOwned() )
    {
      m_data = new char[m_size+1];
      memcpy( m_data, m_start, m_size );
      m_data[m_size] = '\0';
      m_start = m_data;
    }
}
auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef
{
  if ( start < m_size )
         return StringRef( m_start+start, size );
  else
    return StringRef();
}
auto StringRef::operator == ( StringRef const &other ) const noexcept -> bool
{
  return
  size() == other.size() &&
  (std::strncmp( m_start, other.m_start, size() ) == 0);
}
auto StringRef::operator != ( StringRef const &other ) const noexcept -> bool
{
  return !operator==( other );
}

auto StringRef::operator[](size_type index) const noexcept -> char
{
  return m_start[index];
}

auto StringRef::numberOfCharacters() const noexcept -> size_type
{
  size_type noChars = m_size;
  // Make adjustments for uft encodings
  for ( size_type i=0; i < m_size; ++i )
    {
      char c = m_start[i];
      if ( ( c & byte_2_lead ) == byte_2_lead )
        {
          noChars--;
          if (( c & byte_3_lead ) == byte_3_lead )
            noChars--;
          if ( ( c & byte_4_lead ) == byte_4_lead )
            noChars--;
        }
    }
  return noChars;
}

auto operator + ( StringRef const &lhs, StringRef const &rhs ) -> std::string
{
  std::string str;
  str.reserve( lhs.size() + rhs.size() );
  str += lhs;
  str += rhs;
  return str;
}
auto operator + ( StringRef const &lhs, const char *rhs ) -> std::string
{
  return std::string( lhs ) + std::string( rhs );
}
auto operator + ( char const *lhs, StringRef const &rhs ) -> std::string
{
  return std::string( lhs ) + std::string( rhs );
}

auto operator << ( std::ostream &os, StringRef const &str ) -> std::ostream &
{
  return os.write(str.currentData(), str.size());
}

auto operator+=( std::string &lhs, StringRef const &rhs ) -> std::string &
{
  lhs.append(rhs.currentData(), rhs.size());
  return lhs;
}

              } // namespace Catch

#if defined(__clang__)
#    pragma clang diagnostic pop
#endif
// end catch_stringref.cpp
// start catch_tag_alias.cpp

namespace Catch
{
TagAlias::TagAlias(std::string const &_tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}
}
// end catch_tag_alias.cpp
// start catch_tag_alias_autoregistrar.cpp

namespace Catch
{

  RegistrarForTagAliases::RegistrarForTagAliases(char const *alias, char const *tag, SourceLineInfo const &lineInfo)
{
  try
    {
      getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
    }
  catch (...)
    {
      // Do not throw when constructing global objects, instead register the exception to be processed later
      getMutableRegistryHub().registerStartupException();
    }
}

}
// end catch_tag_alias_autoregistrar.cpp
// start catch_tag_alias_registry.cpp

#include <sstream>

namespace Catch
{

TagAliasRegistry::~TagAliasRegistry() {}

TagAlias const *TagAliasRegistry::find( std::string const &alias ) const
{
  auto it = m_registry.find( alias );
  if ( it != m_registry.end() )
    return &(it->second);
  else
    return nullptr;
}

std::string TagAliasRegistry::expandAliases( std::string const &unexpandedTestSpec ) const
{
  std::string expandedTestSpec = unexpandedTestSpec;
  for ( auto const &registryKvp : m_registry )
    {
      std::size_t pos = expandedTestSpec.find( registryKvp.first );
      if ( pos != std::string::npos )
        {
          expandedTestSpec =  expandedTestSpec.substr( 0, pos ) +
          registryKvp.second.tag +
          expandedTestSpec.substr( pos + registryKvp.first.size() );
        }
    }
  return expandedTestSpec;
}

void TagAliasRegistry::add( std::string const &alias, std::string const &tag, SourceLineInfo const &lineInfo )
{
  CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'),
                 "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo );

                                        CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,
                                                       "error: tag alias, '" << alias << "' already registered.\n"
                                                                              << "\tFirst seen at: " << find(alias)->lineInfo << "\n"
                                                                                  << "\tRedefined at: " << lineInfo );
}

ITagAliasRegistry::~ITagAliasRegistry() {}

ITagAliasRegistry const &ITagAliasRegistry::get()
{
  return getRegistryHub().getTagAliasRegistry();
}

                                                                                } // end namespace Catch
// end catch_tag_alias_registry.cpp
// start catch_test_case_info.cpp

#include <cctype>
#include <exception>
#include <algorithm>
#include <sstream>

namespace Catch
{

  TestCaseInfo::SpecialProperties parseSpecialTag( std::string const &tag )
{
  if ( startsWith( tag, '.' ) ||
       tag == "!hide" )
    return TestCaseInfo::IsHidden;
  else if ( tag == "!throws" )
    return TestCaseInfo::Throws;
  else if ( tag == "!shouldfail" )
    return TestCaseInfo::ShouldFail;
  else if ( tag == "!mayfail" )
    return TestCaseInfo::MayFail;
  else if ( tag == "!nonportable" )
    return TestCaseInfo::NonPortable;
  else if ( tag == "!benchmark" )
    return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
  else
    return TestCaseInfo::None;
}
bool isReservedTag( std::string const &tag )
{
  return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
}
void enforceNotReservedTag( std::string const &tag, SourceLineInfo const &_lineInfo )
{
  CATCH_ENFORCE( !isReservedTag(tag),
                 "Tag name: [" << tag << "] is not allowed.\n"
                                       << "Tag names starting with non alpha-numeric characters are reserved\n"
                                        << _lineInfo );
}

                                     TestCase makeTestCase(  ITestInvoker *_testCase,
                                                             std::string const &_className,
                                                             NameAndTags const &nameAndTags,
                                                             SourceLineInfo const &_lineInfo )
{
  bool isHidden = false;

  // Parse out tags
  std::vector<std::string> tags;
  std::string desc, tag;
  bool inTag = false;
  std::string _descOrTags = nameAndTags.tags;
  for (char c : _descOrTags)
    {
      if ( !inTag )
        {
          if ( c == '[' )
            inTag = true;
          else
            desc += c;
        }
      else
        {
          if ( c == ']' )
            {
              TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
              if ( ( prop & TestCaseInfo::IsHidden ) != 0 )
                isHidden = true;
              else if ( prop == TestCaseInfo::None )
                enforceNotReservedTag( tag, _lineInfo );

              tags.push_back( tag );
              tag.clear();
              inTag = false;
            }
          else
            tag += c;
        }
    }
  if ( isHidden )
    {
      tags.push_back( "." );
    }

  TestCaseInfo info( nameAndTags.name, _className, desc, tags, _lineInfo );
  return TestCase( _testCase, std::move(info) );
}

void setTags( TestCaseInfo &testCaseInfo, std::vector<std::string> tags )
{
  std::sort(begin(tags), end(tags));
  tags.erase(std::unique(begin(tags), end(tags)), end(tags));
  testCaseInfo.lcaseTags.clear();

  for ( auto const &tag : tags )
    {
      std::string lcaseTag = toLower( tag );
      testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
      testCaseInfo.lcaseTags.push_back( lcaseTag );
    }
  testCaseInfo.tags = std::move(tags);
}

TestCaseInfo::TestCaseInfo( std::string const &_name,
                            std::string const &_className,
                            std::string const &_description,
                            std::vector<std::string> const &_tags,
                            SourceLineInfo const &_lineInfo )
:   name( _name ),
className( _className ),
description( _description ),
lineInfo( _lineInfo ),
properties( None )
{
  setTags( *this, _tags );
}

bool TestCaseInfo::isHidden() const
{
  return ( properties & IsHidden ) != 0;
}
bool TestCaseInfo::throws() const
{
  return ( properties & Throws ) != 0;
}
bool TestCaseInfo::okToFail() const
{
  return ( properties & (ShouldFail | MayFail ) ) != 0;
}
bool TestCaseInfo::expectedToFail() const
{
  return ( properties & (ShouldFail ) ) != 0;
}

std::string TestCaseInfo::tagsAsString() const
{
  std::string ret;
  // '[' and ']' per tag
  std::size_t full_size = 2 * tags.size();
  for (const auto &tag : tags)
    {
      full_size += tag.size();
    }
  ret.reserve(full_size);
  for (const auto &tag : tags)
    {
      ret.push_back('[');
      ret.append(tag);
      ret.push_back(']');
    }

  return ret;
}

TestCase::TestCase( ITestInvoker *testCase, TestCaseInfo &&info ) : TestCaseInfo( std::move(info) ), test( testCase ) {}

TestCase TestCase::withName( std::string const &_newName ) const
{
  TestCase other( *this );
  other.name = _newName;
  return other;
}

void TestCase::invoke() const
{
  test->invoke();
}

bool TestCase::operator == ( TestCase const &other ) const
{
  return  test.get() == other.test.get() &&
  name == other.name &&
  className == other.className;
}

bool TestCase::operator < ( TestCase const &other ) const
{
  return name < other.name;
}

TestCaseInfo const &TestCase::getTestCaseInfo() const
{
  return *this;
}

            } // end namespace Catch
// end catch_test_case_info.cpp
// start catch_test_case_registry_impl.cpp

#include <sstream>

namespace Catch
{

  std::vector<TestCase> sortTests( IConfig const &config, std::vector<TestCase> const &unsortedTestCases )
{

  std::vector<TestCase> sorted = unsortedTestCases;

  switch ( config.runOrder() )
    {
      case RunTests::InLexicographicalOrder:
        std::sort( sorted.begin(), sorted.end() );
        break;
      case RunTests::InRandomOrder:
        seedRng( config );
        RandomNumberGenerator::shuffle( sorted );
        break;
      case RunTests::InDeclarationOrder:
        // already in declaration order
        break;
    }
  return sorted;
}
bool matchTest( TestCase const &testCase, TestSpec const &testSpec, IConfig const &config )
{
  return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
}

void enforceNoDuplicateTestCases( std::vector<TestCase> const &functions )
{
  std::set<TestCase> seenFunctions;
  for ( auto const &function : functions )
    {
      auto prev = seenFunctions.insert( function );
      CATCH_ENFORCE( prev.second,
                     "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n"
                                                              << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
                                                                                     << "\tRedefined at " << function.getTestCaseInfo().lineInfo );
    }
}

                                                                               std::vector<TestCase> filterTests( std::vector<TestCase> const &testCases, TestSpec const &testSpec, IConfig const &config )
{
  std::vector<TestCase> filtered;
  filtered.reserve( testCases.size() );
  for ( auto const &testCase : testCases )
    if ( matchTest( testCase, testSpec, config ) )
      filtered.push_back( testCase );
  return filtered;
}
std::vector<TestCase> const &getAllTestCasesSorted( IConfig const &config )
{
  return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
}

void TestRegistry::registerTest( TestCase const &testCase )
{
  std::string name = testCase.getTestCaseInfo().name;
  if ( name.empty() )
    {
      ReusableStringStream rss;
      rss << "Anonymous test case " << ++m_unnamedCount;
           return registerTest( testCase.withName( rss.str() ) );
    }
       m_functions.push_back( testCase );
}

std::vector<TestCase> const &TestRegistry::getAllTests() const
{
  return m_functions;
}
std::vector<TestCase> const &TestRegistry::getAllTestsSorted( IConfig const &config ) const
{
  if ( m_sortedFunctions.empty() )
    enforceNoDuplicateTestCases( m_functions );

  if (  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() )
    {
      m_sortedFunctions = sortTests( config, m_functions );
      m_currentSortOrder = config.runOrder();
    }
  return m_sortedFunctions;
}

///////////////////////////////////////////////////////////////////////////
TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept :
m_testAsFunction( testAsFunction ) {}

void TestInvokerAsFunction::invoke() const
{
  m_testAsFunction();
}

std::string extractClassName( StringRef const &classOrQualifiedMethodName )
{
  std::string className = classOrQualifiedMethodName;
  if ( startsWith( className, '&' ) )
    {
      std::size_t lastColons = className.rfind( "::" );
      std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
      if ( penultimateColons == std::string::npos )
        penultimateColons = 1;
      className = className.substr( penultimateColons, lastColons-penultimateColons );
    }
  return className;
}

           } // end namespace Catch
// end catch_test_case_registry_impl.cpp
// start catch_test_case_tracker.cpp

#include <algorithm>
#include <cassert>
#include <stdexcept>
#include <memory>
#include <sstream>

#if defined(__clang__)
#    pragma clang diagnostic push
#    pragma clang diagnostic ignored "-Wexit-time-destructors"
#endif

namespace Catch
{
  namespace TestCaseTracking
  {

    NameAndLocation::NameAndLocation( std::string const &_name, SourceLineInfo const &_location )
    :   name( _name ),
    location( _location )
{}

ITracker::~ITracker() = default;

TrackerContext &TrackerContext::instance()
{
  static TrackerContext s_instance;
  return s_instance;
}

ITracker &TrackerContext::startRun()
{
  m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr );
  m_currentTracker = nullptr;
  m_runState = Executing;
  return *m_rootTracker;
}

void TrackerContext::endRun()
{
  m_rootTracker.reset();
  m_currentTracker = nullptr;
  m_runState = NotStarted;
}

void TrackerContext::startCycle()
{
  m_currentTracker = m_rootTracker.get();
  m_runState = Executing;
}
void TrackerContext::completeCycle()
{
  m_runState = CompletedCycle;
}

bool TrackerContext::completedCycle() const
{
  return m_runState == CompletedCycle;
}
ITracker &TrackerContext::currentTracker()
{
  return *m_currentTracker;
}
void TrackerContext::setCurrentTracker( ITracker *tracker )
{
  m_currentTracker = tracker;
}

TrackerBase::TrackerHasName::TrackerHasName( NameAndLocation const &nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {}
bool TrackerBase::TrackerHasName::operator ()( ITrackerPtr const &tracker ) const
{
  return
  tracker->nameAndLocation().name == m_nameAndLocation.name &&
  tracker->nameAndLocation().location == m_nameAndLocation.location;
}

TrackerBase::TrackerBase( NameAndLocation const &nameAndLocation, TrackerContext &ctx, ITracker *parent )
:   m_nameAndLocation( nameAndLocation ),
m_ctx( ctx ),
m_parent( parent )
{}

NameAndLocation const &TrackerBase::nameAndLocation() const
{
  return m_nameAndLocation;
}
bool TrackerBase::isComplete() const
{
  return m_runState == CompletedSuccessfully || m_runState == Failed;
}
bool TrackerBase::isSuccessfullyCompleted() const
{
  return m_runState == CompletedSuccessfully;
}
bool TrackerBase::isOpen() const
{
  return m_runState != NotStarted && !isComplete();
}
bool TrackerBase::hasChildren() const
{
  return !m_children.empty();
}

void TrackerBase::addChild( ITrackerPtr const &child )
{
  m_children.push_back( child );
}

ITrackerPtr TrackerBase::findChild( NameAndLocation const &nameAndLocation )
{
  auto it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) );
  return ( it != m_children.end() )
  ? *it
  : nullptr;
}
ITracker &TrackerBase::parent()
{
  assert( m_parent ); // Should always be non-null except for root
  return *m_parent;
}

void TrackerBase::openChild()
{
  if ( m_runState != ExecutingChildren )
    {
      m_runState = ExecutingChildren;
      if ( m_parent )
        m_parent->openChild();
    }
}

bool TrackerBase::isSectionTracker() const
{
  return false;
}
bool TrackerBase::isIndexTracker() const
{
  return false;
}

void TrackerBase::open()
{
  m_runState = Executing;
  moveToThis();
  if ( m_parent )
    m_parent->openChild();
}

void TrackerBase::close()
{

  // Close any still open children (e.g. generators)
  while ( &m_ctx.currentTracker() != this )
    m_ctx.currentTracker().close();

  switch ( m_runState )
    {
      case NeedsAnotherRun:
        break;

      case Executing:
        m_runState = CompletedSuccessfully;
        break;
      case ExecutingChildren:
        if ( m_children.empty() || m_children.back()->isComplete() )
          m_runState = CompletedSuccessfully;
        break;

      case NotStarted:
      case CompletedSuccessfully:
      case Failed:
        CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState );

      default:
        CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState );
    }
  moveToParent();
  m_ctx.completeCycle();
}
void TrackerBase::fail()
{
  m_runState = Failed;
  if ( m_parent )
    m_parent->markAsNeedingAnotherRun();
  moveToParent();
  m_ctx.completeCycle();
}
void TrackerBase::markAsNeedingAnotherRun()
{
  m_runState = NeedsAnotherRun;
}

void TrackerBase::moveToParent()
{
  assert( m_parent );
  m_ctx.setCurrentTracker( m_parent );
}
void TrackerBase::moveToThis()
{
  m_ctx.setCurrentTracker( this );
}

SectionTracker::SectionTracker( NameAndLocation const &nameAndLocation, TrackerContext &ctx, ITracker *parent )
:   TrackerBase( nameAndLocation, ctx, parent )
{
  if ( parent )
    {
      while ( !parent->isSectionTracker() )
        parent = &parent->parent();

      SectionTracker &parentSection = static_cast<SectionTracker &>( *parent );
      addNextFilters( parentSection.m_filters );
    }
}

bool SectionTracker::isSectionTracker() const
{
  return true;
}

SectionTracker &SectionTracker::acquire( TrackerContext &ctx, NameAndLocation const &nameAndLocation )
{
  std::shared_ptr<SectionTracker> section;

  ITracker &currentTracker = ctx.currentTracker();
  if ( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) )
    {
      assert( childTracker );
      assert( childTracker->isSectionTracker() );
      section = std::static_pointer_cast<SectionTracker>( childTracker );
    }
  else
    {
      section = std::make_shared<SectionTracker>( nameAndLocation, ctx, &currentTracker );
      currentTracker.addChild( section );
    }
  if ( !ctx.completedCycle() )
    section->tryOpen();
  return *section;
}

void SectionTracker::tryOpen()
{
  if ( !isComplete() && (m_filters.empty() || m_filters[0].empty() ||  m_filters[0] == m_nameAndLocation.name ) )
    open();
}

void SectionTracker::addInitialFilters( std::vector<std::string> const &filters )
{
  if ( !filters.empty() )
    {
      m_filters.push_back(""); // Root - should never be consulted
      m_filters.push_back(""); // Test Case - not a section filter
      m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
    }
}
void SectionTracker::addNextFilters( std::vector<std::string> const &filters )
{
  if ( filters.size() > 1 )
    m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() );
}

IndexTracker::IndexTracker( NameAndLocation const &nameAndLocation, TrackerContext &ctx, ITracker *parent, int size )
:   TrackerBase( nameAndLocation, ctx, parent ),
m_size( size )
{}

bool IndexTracker::isIndexTracker() const
{
  return true;
}

IndexTracker &IndexTracker::acquire( TrackerContext &ctx, NameAndLocation const &nameAndLocation, int size )
{
  std::shared_ptr<IndexTracker> tracker;

  ITracker &currentTracker = ctx.currentTracker();
  if ( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) )
    {
      assert( childTracker );
      assert( childTracker->isIndexTracker() );
      tracker = std::static_pointer_cast<IndexTracker>( childTracker );
    }
  else
    {
      tracker = std::make_shared<IndexTracker>( nameAndLocation, ctx, &currentTracker, size );
      currentTracker.addChild( tracker );
    }

  if ( !ctx.completedCycle() && !tracker->isComplete() )
    {
      if ( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
        tracker->moveNext();
      tracker->open();
    }

  return *tracker;
}

int IndexTracker::index() const
{
  return m_index;
}

void IndexTracker::moveNext()
{
  m_index++;
  m_children.clear();
}

void IndexTracker::close()
{
  TrackerBase::close();
  if ( m_runState == CompletedSuccessfully && m_index < m_size-1 )
         m_runState = Executing;
}

   } // namespace TestCaseTracking

using TestCaseTracking::ITracker;
using TestCaseTracking::TrackerContext;
using TestCaseTracking::SectionTracker;
using TestCaseTracking::IndexTracker;

                          } // namespace Catch

#if defined(__clang__)
#    pragma clang diagnostic pop
#endif
// end catch_test_case_tracker.cpp
// start catch_test_registry.cpp

namespace Catch
{

  auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker *
{
  return new(std::nothrow) TestInvokerAsFunction( testAsFunction );
}

NameAndTags::NameAndTags( StringRef const &name_ , StringRef const &tags_ ) noexcept :
name( name_ ), tags( tags_ ) {}

AutoReg::AutoReg( ITestInvoker *invoker, SourceLineInfo const &lineInfo, StringRef const &classOrMethod, NameAndTags const &nameAndTags ) noexcept
{
  try {
      getMutableRegistryHub()
      .registerTest(
        makeTestCase(
          invoker,
          extractClassName( classOrMethod ),
          nameAndTags,
          lineInfo));
    }
  catch (...)
    {
      // Do not throw when constructing global objects, instead register the exception to be processed later
      getMutableRegistryHub().registerStartupException();
    }
}

AutoReg::~AutoReg() = default;
}
// end catch_test_registry.cpp
// start catch_test_spec.cpp

#include <algorithm>
#include <string>
#include <vector>
#include <memory>

namespace Catch
{

  TestSpec::Pattern::~Pattern() = default;
  TestSpec::NamePattern::~NamePattern() = default;
  TestSpec::TagPattern::~TagPattern() = default;
  TestSpec::ExcludedPattern::~ExcludedPattern() = default;

  TestSpec::NamePattern::NamePattern( std::string const &name )
  : m_wildcardPattern( toLower( name ), CaseSensitive::No )
{}
bool TestSpec::NamePattern::matches( TestCaseInfo const &testCase ) const
{
  return m_wildcardPattern.matches( toLower( testCase.name ) );
}

TestSpec::TagPattern::TagPattern( std::string const &tag ) : m_tag( toLower( tag ) ) {}
bool TestSpec::TagPattern::matches( TestCaseInfo const &testCase ) const
{
  return std::find(begin(testCase.lcaseTags),
                   end(testCase.lcaseTags),
                   m_tag) != end(testCase.lcaseTags);
}

TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const &underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
bool TestSpec::ExcludedPattern::matches( TestCaseInfo const &testCase ) const
{
  return !m_underlyingPattern->matches( testCase );
}

bool TestSpec::Filter::matches( TestCaseInfo const &testCase ) const
{
  // All patterns in a filter must match for the filter to be a match
  for ( auto const &pattern : m_patterns )
    {
      if ( !pattern->matches( testCase ) )
        return false;
    }
  return true;
}

bool TestSpec::hasFilters() const
{
  return !m_filters.empty();
}
bool TestSpec::matches( TestCaseInfo const &testCase ) const
{
  // A TestSpec matches if any filter matches
  for ( auto const &filter : m_filters )
    if ( filter.matches( testCase ) )
      return true;
  return false;
}
}
// end catch_test_spec.cpp
// start catch_test_spec_parser.cpp

namespace Catch
{

TestSpecParser::TestSpecParser( ITagAliasRegistry const &tagAliases ) : m_tagAliases( &tagAliases ) {}

TestSpecParser &TestSpecParser::parse( std::string const &arg )
{
  m_mode = None;
  m_exclusion = false;
  m_start = std::string::npos;
  m_arg = m_tagAliases->expandAliases( arg );
  m_escapeChars.clear();
  for ( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
          visitChar( m_arg[m_pos] );
  if ( m_mode == Name )
    addPattern<TestSpec::NamePattern>();
  return *this;
}
TestSpec TestSpecParser::testSpec()
{
  addFilter();
  return m_testSpec;
}

void TestSpecParser::visitChar( char c )
{
  if ( m_mode == None )
    {
      switch ( c )
        {
          case ' ':
            return;
          case '~':
            m_exclusion = true;
            return;
          case '[':
            return startNewMode( Tag, ++m_pos );
          case '"':
            return startNewMode( QuotedName, ++m_pos );
          case '\\':
            return escape();
          default:
            startNewMode( Name, m_pos );
            break;
        }
    }
  if ( m_mode == Name )
    {
      if ( c == ',' )
        {
          addPattern<TestSpec::NamePattern>();
          addFilter();
        }
      else if ( c == '[' )
        {
          if ( subString() == "exclude:" )
            m_exclusion = true;
          else
            addPattern<TestSpec::NamePattern>();
          startNewMode( Tag, ++m_pos );
        }
      else if ( c == '\\' )
        escape();
    }
  else if ( m_mode == EscapedName )
    m_mode = Name;
  else if ( m_mode == QuotedName && c == '"' )
    addPattern<TestSpec::NamePattern>();
  else if ( m_mode == Tag && c == ']' )
    addPattern<TestSpec::TagPattern>();
}
void TestSpecParser::startNewMode( Mode mode, std::size_t start )
{
  m_mode = mode;
  m_start = start;
}
void TestSpecParser::escape()
{
  if ( m_mode == None )
    m_start = m_pos;
  m_mode = EscapedName;
  m_escapeChars.push_back( m_pos );
}
std::string TestSpecParser::subString() const
{
  return m_arg.substr( m_start, m_pos - m_start );
}

void TestSpecParser::addFilter()
{
  if ( !m_currentFilter.m_patterns.empty() )
    {
      m_testSpec.m_filters.push_back( m_currentFilter );
      m_currentFilter = TestSpec::Filter();
    }
}

TestSpec parseTestSpec( std::string const &arg )
{
  return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
}

          } // namespace Catch
// end catch_test_spec_parser.cpp
// start catch_timer.cpp

#include <chrono>

static const uint64_t nanosecondsInSecond = 1000000000;

namespace Catch
{

  auto getCurrentNanosecondsSinceEpoch() -> uint64_t
  {
    return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
  }

  auto estimateClockResolution() -> uint64_t
  {
    uint64_t sum = 0;
    static const uint64_t iterations = 1000000;

    auto startTime = getCurrentNanosecondsSinceEpoch();

    for ( std::size_t i = 0; i < iterations; ++i )
      {

        uint64_t ticks;
        uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
        do
          {
            ticks = getCurrentNanosecondsSinceEpoch();
          }
        while ( ticks == baseTicks );

        auto delta = ticks - baseTicks;
        sum += delta;

        // If we have been calibrating for over 3 seconds -- the clock
        // is terrible and we should move on.
        // TBD: How to signal that the measured resolution is probably wrong?
        if (ticks > startTime + 3 * nanosecondsInSecond)
          {
            return sum / i;
          }
      }

    // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
    // - and potentially do more iterations if there's a high variance.
    return sum/iterations;
  }
  auto getEstimatedClockResolution() -> uint64_t
  {
    static auto s_resolution = estimateClockResolution();
    return s_resolution;
  }

  void Timer::start()
  {
    m_nanoseconds = getCurrentNanosecondsSinceEpoch();
  }
  auto Timer::getElapsedNanoseconds() const -> uint64_t
  {
    return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
  }
  auto Timer::getElapsedMicroseconds() const -> uint64_t
  {
    return getElapsedNanoseconds()/1000;
  }
  auto Timer::getElapsedMilliseconds() const -> unsigned int
  {
    return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
  }
  auto Timer::getElapsedSeconds() const -> double
  {
    return getElapsedMicroseconds()/1000000.0;
  }

} // namespace Catch
// end catch_timer.cpp
// start catch_tostring.cpp

#if defined(__clang__)
#    pragma clang diagnostic push
#    pragma clang diagnostic ignored "-Wexit-time-destructors"
#    pragma clang diagnostic ignored "-Wglobal-constructors"
#endif

// Enable specific decls locally
#if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
#endif

#include <cmath>
#include <iomanip>

namespace Catch
{

  namespace Detail
  {

    const std::string unprintableString = "{?}";

    namespace
    {
      const int hexThreshold = 255;

      struct Endianness
      {
        enum Arch { Big, Little };

        static Arch which()
  {
    union _
    {
      int asInt;
      char asChar[sizeof (int)];
    } u;

    u.asInt = 1;
    return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
  }
      };
    }

  std::string rawMemoryToString( const void *object, std::size_t size )
  {
    // Reverse order for little endian architectures
    int i = 0, end = static_cast<int>( size ), inc = 1;
    if ( Endianness::which() == Endianness::Little )
      {
        i = end-1;
        end = inc = -1;
      }

    unsigned char const *bytes = static_cast<unsigned char const *>(object);
    ReusableStringStream rss;
    rss << "0x" << std::setfill('0') << std::hex;
                 for ( ; i != end; i += inc )
                   rss << std::setw(2) << static_cast<unsigned>(bytes[i]);
                      return rss.str();
  }
                                                 }

               template<typename T>
               std::string fpToString( T value, int precision )
  {
    if (std::isnan(value))
      {
        return "nan";
      }

    ReusableStringStream rss;
    rss << std::setprecision( precision )
         << std::fixed
          << value;
          std::string d = rss.str();
          std::size_t i = d.find_last_not_of( '0' );
          if ( i != std::string::npos && i != d.size()-1 )
      {
        if ( d[i] == '.' )
          i++;
        d = d.substr( 0, i+1 );
      }
    return d;
  }

//// ======================================================= ////
//
//   Out-of-line defs for full specialization of StringMaker
//
//// ======================================================= ////

  std::string StringMaker<std::string>::convert(const std::string &str)
  {
    if (!getCurrentContext().getConfig()->showInvisibles())
      {
        return '"' + str + '"';
      }

    std::string s("\"");
    for (char c : str)
      {
        switch (c)
          {
            case '\n':
              s.append("\\n");
              break;
            case '\t':
              s.append("\\t");
              break;
            default:
              s.push_back(c);
              break;
          }
      }
    s.append("\"");
    return s;
  }

#ifdef CATCH_CONFIG_WCHAR
  std::string StringMaker<std::wstring>::convert(const std::wstring &wstr)
  {
    std::string s;
    s.reserve(wstr.size());
    for (auto c : wstr)
      {
        s += (c <= 0xff) ? static_cast<char>(c) : '?';
      }
    return ::Catch::Detail::stringify(s);
  }
#endif

  std::string StringMaker<char const *>::convert(char const *str)
  {
    if (str)
      {
        return ::Catch::Detail::stringify(std::string { str });
      }
    else
      {
        return { "{null string}" };
      }
  }
  std::string StringMaker<char *>::convert(char *str)
  {
    if (str)
      {
        return ::Catch::Detail::stringify(std::string { str });
      }
    else
      {
        return { "{null string}" };
      }
  }
#ifdef CATCH_CONFIG_WCHAR
  std::string StringMaker<wchar_t const *>::convert(wchar_t const *str)
  {
    if (str)
      {
        return ::Catch::Detail::stringify(std::wstring { str });
      }
    else
      {
        return { "{null string}" };
      }
  }
  std::string StringMaker<wchar_t *>::convert(wchar_t *str)
  {
    if (str)
      {
        return ::Catch::Detail::stringify(std::wstring { str });
      }
    else
      {
        return { "{null string}" };
      }
  }
#endif

  std::string StringMaker<int>::convert(int value)
  {
    return ::Catch::Detail::stringify(static_cast<long long>(value));
  }
  std::string StringMaker<long>::convert(long value)
  {
    return ::Catch::Detail::stringify(static_cast<long long>(value));
  }
  std::string StringMaker<long long>::convert(long long value)
  {
    ReusableStringStream rss;
    rss << value;
    if (value > Detail::hexThreshold)
      {
        rss << " (0x" << std::hex << value << ')';
      }
                               return rss.str();
  }

                 std::string StringMaker<unsigned int>::convert(unsigned int value)
  {
    return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
  }
  std::string StringMaker<unsigned long>::convert(unsigned long value)
  {
    return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));
  }
  std::string StringMaker<unsigned long long>::convert(unsigned long long value)
  {
    ReusableStringStream rss;
    rss << value;
    if (value > Detail::hexThreshold)
      {
        rss << " (0x" << std::hex << value << ')';
      }
                               return rss.str();
  }

                 std::string StringMaker<bool>::convert(bool b)
  {
    return b ? "true" : "false";
  }

  std::string StringMaker<char>::convert(char value)
  {
    if (value == '\r')
      {
        return "'\\r'";
      }
    else if (value == '\f')
      {
        return "'\\f'";
      }
    else if (value == '\n')
      {
        return "'\\n'";
      }
    else if (value == '\t')
      {
        return "'\\t'";
      }
    else if ('\0' <= value && value < ' ')
      {
        return ::Catch::Detail::stringify(static_cast<unsigned int>(value));
      }
    else
      {
        char chstr[] = "' '";
        chstr[1] = value;
        return chstr;
      }
  }
  std::string StringMaker<signed char>::convert(signed char c)
  {
    return ::Catch::Detail::stringify(static_cast<char>(c));
  }
  std::string StringMaker<unsigned char>::convert(unsigned char c)
  {
    return ::Catch::Detail::stringify(static_cast<char>(c));
  }

  std::string StringMaker<std::nullptr_t>::convert(std::nullptr_t)
  {
    return "nullptr";
  }

  std::string StringMaker<float>::convert(float value)
  {
    return fpToString(value, 5) + 'f';
  }
  std::string StringMaker<double>::convert(double value)
  {
    return fpToString(value, 10);
  }

  std::string ratio_string<std::atto>::symbol()
  {
    return "a";
  }
  std::string ratio_string<std::femto>::symbol()
  {
    return "f";
  }
  std::string  ratio_string<std::pico>::symbol()
  {
    return "p";
  }
  std::string  ratio_string<std::nano>::symbol()
  {
    return "n";
  }
  std::string ratio_string<std::micro>::symbol()
  {
    return "u";
  }
  std::string ratio_string<std::milli>::symbol()
  {
    return "m";
  }

} // end namespace Catch

#if defined(__clang__)
#    pragma clang diagnostic pop
#endif

// end catch_tostring.cpp
// start catch_totals.cpp

namespace Catch
{

  Counts Counts::operator - ( Counts const &other ) const
  {
    Counts diff;
    diff.passed = passed - other.passed;
    diff.failed = failed - other.failed;
    diff.failedButOk = failedButOk - other.failedButOk;
    return diff;
  }

  Counts &Counts::operator += ( Counts const &other )
  {
    passed += other.passed;
    failed += other.failed;
    failedButOk += other.failedButOk;
    return *this;
  }

  std::size_t Counts::total() const
  {
    return passed + failed + failedButOk;
  }
  bool Counts::allPassed() const
  {
    return failed == 0 && failedButOk == 0;
  }
  bool Counts::allOk() const
  {
    return failed == 0;
  }

  Totals Totals::operator - ( Totals const &other ) const
  {
    Totals diff;
    diff.assertions = assertions - other.assertions;
    diff.testCases = testCases - other.testCases;
    return diff;
  }

  Totals &Totals::operator += ( Totals const &other )
  {
    assertions += other.assertions;
    testCases += other.testCases;
    return *this;
  }

  Totals Totals::delta( Totals const &prevTotals ) const
  {
    Totals diff = *this - prevTotals;
    if ( diff.assertions.failed > 0 )
      ++diff.testCases.failed;
    else if ( diff.assertions.failedButOk > 0 )
      ++diff.testCases.failedButOk;
    else
      ++diff.testCases.passed;
    return diff;
  }

}
// end catch_totals.cpp
// start catch_uncaught_exceptions.cpp

#include <exception>

namespace Catch
{
  bool uncaught_exceptions()
  {
#if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
    return std::uncaught_exceptions() > 0;
#else
    return std::uncaught_exception();
#endif
  }
} // end namespace Catch
// end catch_uncaught_exceptions.cpp
// start catch_version.cpp

#include <ostream>

namespace Catch
{

  Version::Version
  (   unsigned int _majorVersion,
      unsigned int _minorVersion,
      unsigned int _patchNumber,
      char const *const _branchName,
      unsigned int _buildNumber )
    :   majorVersion( _majorVersion ),
        minorVersion( _minorVersion ),
        patchNumber( _patchNumber ),
        branchName( _branchName ),
        buildNumber( _buildNumber )
  {}

  std::ostream &operator << ( std::ostream &os, Version const &version )
  {
    os  << version.majorVersion << '.'
                                 << version.minorVersion << '.'
                                                          << version.patchNumber;
                                                          // branchName is never null -> 0th char is \0 if it is empty
                                                          if (version.branchName[0])
      {
        os << '-' << version.branchName
                   << '.' << version.buildNumber;
      }
                return os;
  }

             Version const &libraryVersion()
  {
    static Version version( 2, 2, 3, "", 0 );
    return version;
  }

}
// end catch_version.cpp
// start catch_wildcard_pattern.cpp

#include <sstream>

namespace Catch
{

  WildcardPattern::WildcardPattern( std::string const &pattern,
                                    CaseSensitive::Choice caseSensitivity )
    :   m_caseSensitivity( caseSensitivity ),
        m_pattern( adjustCase( pattern ) )
  {
    if ( startsWith( m_pattern, '*' ) )
      {
        m_pattern = m_pattern.substr( 1 );
        m_wildcard = WildcardAtStart;
      }
    if ( endsWith( m_pattern, '*' ) )
      {
        m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
        m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
      }
  }

  bool WildcardPattern::matches( std::string const &str ) const
  {
    switch ( m_wildcard )
      {
        case NoWildcard:
          return m_pattern == adjustCase( str );
        case WildcardAtStart:
          return endsWith( adjustCase( str ), m_pattern );
        case WildcardAtEnd:
          return startsWith( adjustCase( str ), m_pattern );
        case WildcardAtBothEnds:
          return contains( adjustCase( str ), m_pattern );
        default:
          CATCH_INTERNAL_ERROR( "Unknown enum" );
      }
  }

  std::string WildcardPattern::adjustCase( std::string const &str ) const
  {
    return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
  }
}
// end catch_wildcard_pattern.cpp
// start catch_xmlwriter.cpp

#include <iomanip>

using uchar = unsigned char;

namespace Catch
{

  namespace
  {

    size_t trailingBytes(unsigned char c)
  {
    if ((c & 0xE0) == 0xC0)
      {
        return 2;
      }
    if ((c & 0xF0) == 0xE0)
      {
        return 3;
      }
    if ((c & 0xF8) == 0xF0)
      {
        return 4;
      }
    CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
  }

  uint32_t headerValue(unsigned char c)
  {
    if ((c & 0xE0) == 0xC0)
      {
        return c & 0x1F;
      }
    if ((c & 0xF0) == 0xE0)
      {
        return c & 0x0F;
      }
    if ((c & 0xF8) == 0xF0)
      {
        return c & 0x07;
      }
    CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered");
  }

  void hexEscapeChar(std::ostream &os, unsigned char c)
  {
    os << "\\x"
        << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
                                                            << static_cast<int>(c);
  }

                                                                        } // anonymous namespace

                                     XmlEncode::XmlEncode( std::string const &str, ForWhat forWhat )
                                       :   m_str( str ),
                                           m_forWhat( forWhat )
  {}

  void XmlEncode::encodeTo( std::ostream &os ) const
  {
    // Apostrophe escaping not necessary if we always use " to write attributes
    // (see: http://www.w3.org/TR/xml/#syntax)

    for ( std::size_t idx = 0; idx < m_str.size(); ++ idx )
      {
        uchar c = m_str[idx];
        switch (c)
          {
            case '<':
              os << "&lt;";
              break;
            case '&':
              os << "&amp;";
              break;

            case '>':
              // See: http://www.w3.org/TR/xml/#syntax
              if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')
                os << "&gt;";
              else
                os << c;
              break;

            case '\"':
              if (m_forWhat == ForAttributes)
                os << "&quot;";
              else
                os << c;
              break;

            default:
              // Check for control characters and invalid utf-8

              // Escape control characters in standard ascii
              // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
              if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F)
                {
                  hexEscapeChar(os, c);
                  break;
                }

              // Plain ASCII: Write it to stream
              if (c < 0x7F)
                {
                  os << c;
                  break;
                }

              // UTF-8 territory
              // Check if the encoding is valid and if it is not, hex escape bytes.
              // Important: We do not check the exact decoded values for validity, only the encoding format
              // First check that this bytes is a valid lead byte:
              // This means that it is not encoded as 1111 1XXX
              // Or as 10XX XXXX
              if (c <  0xC0 ||
                       c >= 0xF8)
                {
                  hexEscapeChar(os, c);
                  break;
                }

              auto encBytes = trailingBytes(c);
              // Are there enough bytes left to avoid accessing out-of-bounds memory?
              if (idx + encBytes - 1 >= m_str.size())
                {
                  hexEscapeChar(os, c);
                  break;
                }
              // The header is valid, check data
              // The next encBytes bytes must together be a valid utf-8
              // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)
              bool valid = true;
              uint32_t value = headerValue(c);
              for (std::size_t n = 1; n < encBytes; ++n)
                {
                  uchar nc = m_str[idx + n];
                  valid &= ((nc & 0xC0) == 0x80);
                  value = (value << 6) | (nc & 0x3F);
                }

              if (
                // Wrong bit pattern of following bytes
                (!valid) ||
                // Overlong encodings
                (value < 0x80) ||
                 (0x80 <= value && value < 0x800   && encBytes > 2) ||
                  (0x800 < value && value < 0x10000 && encBytes > 3) ||
                   // Encoded value out of range
                   (value >= 0x110000)
                         )
                {
                  hexEscapeChar(os, c);
                  break;
                }

              // If we got here, this is in fact a valid(ish) utf-8 sequence
              for (std::size_t n = 0; n < encBytes; ++n)
                {
                  os << m_str[idx + n];
                }
              idx += encBytes - 1;
              break;
          }
      }
  }

  std::ostream &operator << ( std::ostream &os, XmlEncode const &xmlEncode )
  {
    xmlEncode.encodeTo( os );
    return os;
  }

  XmlWriter::ScopedElement::ScopedElement( XmlWriter *writer )
    :   m_writer( writer )
  {}

  XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
:
  m_writer( other.m_writer )
  {
    other.m_writer = nullptr;
  }
  XmlWriter::ScopedElement &XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept
  {
    if ( m_writer )
      {
        m_writer->endElement();
      }
    m_writer = other.m_writer;
    other.m_writer = nullptr;
    return *this;
  }

  XmlWriter::ScopedElement::~ScopedElement()
  {
    if ( m_writer )
      m_writer->endElement();
  }

  XmlWriter::ScopedElement &XmlWriter::ScopedElement::writeText( std::string const &text, bool indent )
  {
    m_writer->writeText( text, indent );
    return *this;
  }

  XmlWriter::XmlWriter( std::ostream &os ) : m_os( os )
  {
    writeDeclaration();
  }

  XmlWriter::~XmlWriter()
  {
    while ( !m_tags.empty() )
      endElement();
  }

  XmlWriter &XmlWriter::startElement( std::string const &name )
  {
    ensureTagClosed();
    newlineIfNecessary();
    m_os << m_indent << '<' << name;
                      m_tags.push_back( name );
                      m_indent += "  ";
                      m_tagIsOpen = true;
                      return *this;
  }

                    XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const &name )
  {
    ScopedElement scoped( this );
    startElement( name );
    return scoped;
  }

  XmlWriter &XmlWriter::endElement()
  {
    newlineIfNecessary();
    m_indent = m_indent.substr( 0, m_indent.size()-2 );
    if ( m_tagIsOpen )
      {
        m_os << "/>";
        m_tagIsOpen = false;
      }
    else
      {
        m_os << m_indent << "</" << m_tags.back() << ">";
      }
                              m_os << std::endl;
                              m_tags.pop_back();
                              return *this;
  }

                            XmlWriter &XmlWriter::writeAttribute( std::string const &name, std::string const &attribute )
  {
    if ( !name.empty() && !attribute.empty() )
      m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
                                  return *this;
  }

                                XmlWriter &XmlWriter::writeAttribute( std::string const &name, bool attribute )
  {
    m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
                                  return *this;
  }

                                XmlWriter &XmlWriter::writeText( std::string const &text, bool indent )
  {
    if ( !text.empty() )
      {
        bool tagWasOpen = m_tagIsOpen;
        ensureTagClosed();
        if ( tagWasOpen && indent )
          m_os << m_indent;
        m_os << XmlEncode( text );
        m_needsNewline = true;
      }
    return *this;
  }

  XmlWriter &XmlWriter::writeComment( std::string const &text )
  {
    ensureTagClosed();
    m_os << m_indent << "<!--" << text << "-->";
                                m_needsNewline = true;
                                return *this;
  }

                              void XmlWriter::writeStylesheetRef( std::string const &url )
  {
    m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
  }

                                                        XmlWriter &XmlWriter::writeBlankLine()
  {
    ensureTagClosed();
    m_os << '\n';
    return *this;
  }

  void XmlWriter::ensureTagClosed()
  {
    if ( m_tagIsOpen )
      {
        m_os << ">" << std::endl;
              m_tagIsOpen = false;
      }
  }

  void XmlWriter::writeDeclaration()
  {
    m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
  }

  void XmlWriter::newlineIfNecessary()
  {
    if ( m_needsNewline )
      {
        m_os << std::endl;
        m_needsNewline = false;
      }
  }
}
// end catch_xmlwriter.cpp
// start catch_reporter_bases.cpp

#include <cstring>
#include <cfloat>
#include <cstdio>
#include <cassert>
#include <memory>

namespace Catch
{
  void prepareExpandedExpression(AssertionResult &result)
  {
    result.getExpandedExpression();
  }

  // Because formatting using c++ streams is stateful, drop down to C is required
  // Alternatively we could use stringstream, but its performance is... not good.
  std::string getFormattedDuration( double duration )
  {
    // Max exponent + 1 is required to represent the whole part
    // + 1 for decimal point
    // + 3 for the 3 decimal places
    // + 1 for null terminator
    const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
    char buffer[maxDoubleSize];

    // Save previous errno, to prevent sprintf from overwriting it
    ErrnoGuard guard;
#ifdef _MSC_VER
    sprintf_s(buffer, "%.3f", duration);
#else
    sprintf(buffer, "%.3f", duration);
#endif
    return std::string(buffer);
  }

  TestEventListenerBase::TestEventListenerBase(ReporterConfig const &_config)
    :StreamingReporterBase(_config) {}

  void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}

  bool TestEventListenerBase::assertionEnded(AssertionStats const &)
  {
    return false;
  }

} // end namespace Catch
// end catch_reporter_bases.cpp
// start catch_reporter_compact.cpp

namespace
{

#ifdef CATCH_PLATFORM_MAC
  const char *failedString()
  {
    return "FAILED";
  }
  const char *passedString()
  {
    return "PASSED";
  }
#else
  const char *failedString()
  {
    return "failed";
  }
  const char *passedString()
  {
    return "passed";
  }
#endif

  // Colour::LightGrey
  Catch::Colour::Code dimColour()
  {
    return Catch::Colour::FileName;
  }

  std::string bothOrAll( std::size_t count )
  {
    return count == 1 ? std::string() :
    count == 2 ? "both " : "all " ;
  }

} // anon namespace

namespace Catch
{
  namespace
  {
// Colour, message variants:
// - white: No tests ran.
// -   red: Failed [both/all] N test cases, failed [both/all] M assertions.
// - white: Passed [both/all] N test cases (no assertions).
// -   red: Failed N tests cases, failed M assertions.
// - green: Passed [both/all] N tests cases with M assertions.
    void printTotals(std::ostream &out, const Totals &totals)
  {
    if (totals.testCases.total() == 0)
      {
        out << "No tests ran.";
      }
    else if (totals.testCases.failed == totals.testCases.total())
      {
        Colour colour(Colour::ResultError);
        const std::string qualify_assertions_failed =
        totals.assertions.failed == totals.assertions.total() ?
        bothOrAll(totals.assertions.failed) : std::string();
        out <<
             "Failed " << bothOrAll(totals.testCases.failed)
                        << pluralise(totals.testCases.failed, "test case") << ", "
                                                                            "failed " << qualify_assertions_failed <<
                                                                                       pluralise(totals.assertions.failed, "assertion") << '.';
      }
                                                                                   else if (totals.assertions.total() == 0)
      {
        out <<
             "Passed " << bothOrAll(totals.testCases.total())
                        << pluralise(totals.testCases.total(), "test case")
                         << " (no assertions).";
      }
                     else if (totals.assertions.failed)
      {
        Colour colour(Colour::ResultError);
        out <<
             "Failed " << pluralise(totals.testCases.failed, "test case") << ", "
                                                                           "failed " << pluralise(totals.assertions.failed, "assertion") << '.';
      }
                                                                                  else
      {
        Colour colour(Colour::ResultSuccess);
        out <<
             "Passed " << bothOrAll(totals.testCases.passed)
                        << pluralise(totals.testCases.passed, "test case") <<
                                                                            " with " << pluralise(totals.assertions.passed, "assertion") << '.';
      }
  }

// Implementation of CompactReporter formatting
                                                                      class AssertionPrinter
                                                                      {
                                                                        public:
                                                                        AssertionPrinter &operator= (AssertionPrinter const &) = delete;
                                                                        AssertionPrinter(AssertionPrinter const &) = delete;
                                                                        AssertionPrinter(std::ostream &_stream, AssertionStats const &_stats, bool _printInfoMessages)
                                                                        : stream(_stream)
                                                                        , result(_stats.assertionResult)
                                                                        , messages(_stats.infoMessages)
                                                                        , itMessage(_stats.infoMessages.begin())
  , printInfoMessages(_printInfoMessages) {}

  void print()
  {
    printSourceInfo();

    itMessage = messages.begin();

    switch (result.getResultType())
      {
        case ResultWas::Ok:
          printResultType(Colour::ResultSuccess, passedString());
          printOriginalExpression();
          printReconstructedExpression();
          if (!result.hasExpression())
            printRemainingMessages(Colour::None);
          else
            printRemainingMessages();
          break;
        case ResultWas::ExpressionFailed:
          if (result.isOk())
            printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok"));
          else
            printResultType(Colour::Error, failedString());
          printOriginalExpression();
          printReconstructedExpression();
          printRemainingMessages();
          break;
        case ResultWas::ThrewException:
          printResultType(Colour::Error, failedString());
          printIssue("unexpected exception with message:");
          printMessage();
          printExpressionWas();
          printRemainingMessages();
          break;
        case ResultWas::FatalErrorCondition:
          printResultType(Colour::Error, failedString());
          printIssue("fatal error condition with message:");
          printMessage();
          printExpressionWas();
          printRemainingMessages();
          break;
        case ResultWas::DidntThrowException:
          printResultType(Colour::Error, failedString());
          printIssue("expected exception, got none");
          printExpressionWas();
          printRemainingMessages();
          break;
        case ResultWas::Info:
          printResultType(Colour::None, "info");
          printMessage();
          printRemainingMessages();
          break;
        case ResultWas::Warning:
          printResultType(Colour::None, "warning");
          printMessage();
          printRemainingMessages();
          break;
        case ResultWas::ExplicitFailure:
          printResultType(Colour::Error, failedString());
          printIssue("explicitly");
          printRemainingMessages(Colour::None);
          break;
        // These cases are here to prevent compiler warnings
        case ResultWas::Unknown:
        case ResultWas::FailureBit:
        case ResultWas::Exception:
          printResultType(Colour::Error, "** internal error **");
          break;
      }
  }

  private:
  void printSourceInfo() const
  {
    Colour colourGuard(Colour::FileName);
    stream << result.getSourceInfo() << ':';
  }

          void printResultType(Colour::Code colour, std::string const &passOrFail) const
  {
    if (!passOrFail.empty())
      {
        {
          Colour colourGuard(colour);
          stream << ' ' << passOrFail;
        }
                stream << ':';
      }
  }

  void printIssue(std::string const &issue) const
  {
    stream << ' ' << issue;
  }

          void printExpressionWas()
  {
    if (result.hasExpression())
      {
        stream << ';';
        {
          Colour colour(dimColour());
          stream << " expression was:";
        }
        printOriginalExpression();
      }
  }

  void printOriginalExpression() const
  {
    if (result.hasExpression())
      {
        stream << ' ' << result.getExpression();
      }
  }

  void printReconstructedExpression() const
  {
    if (result.hasExpandedExpression())
      {
        {
          Colour colour(dimColour());
          stream << " for: ";
        }
        stream << result.getExpandedExpression();
      }
  }

  void printMessage()
  {
    if (itMessage != messages.end())
      {
        stream << " '" << itMessage->message << '\'';
                        ++itMessage;
      }
  }

          void printRemainingMessages(Colour::Code colour = dimColour())
  {
    if (itMessage == messages.end())
      return;

    // using messages.end() directly yields (or auto) compilation error:
    std::vector<MessageInfo>::const_iterator itEnd = messages.end();
    const std::size_t N = static_cast<std::size_t>(std::distance(itMessage, itEnd));

    {
      Colour colourGuard(colour);
      stream << " with " << pluralise(N, "message") << ':';
    }

                        for (; itMessage != itEnd; )
      {
        // If this assertion is a warning ignore any INFO messages
        if (printInfoMessages || itMessage->type != ResultWas::Info)
          {
            stream << " '" << itMessage->message << '\'';
                            if (++itMessage != itEnd)
              {
                Colour colourGuard(dimColour());
                stream << " and";
              }
          }
      }
  }

  private:
  std::ostream &stream;
  AssertionResult const &result;
  std::vector<MessageInfo> messages;
  std::vector<MessageInfo>::const_iterator itMessage;
  bool printInfoMessages;
             };

             } // anon namespace

  std::string CompactReporter::getDescription()
  {
    return "Reports test results on a single line, suitable for IDEs";
  }

  ReporterPreferences CompactReporter::getPreferences() const
  {
    ReporterPreferences prefs;
    prefs.shouldRedirectStdOut = false;
    return prefs;
  }

  void CompactReporter::noMatchingTestCases( std::string const &spec )
  {
    stream << "No test cases matched '" << spec << '\'' << std::endl;
  }

  void CompactReporter::assertionStarting( AssertionInfo const &) {}

  bool CompactReporter::assertionEnded( AssertionStats const &_assertionStats )
  {
    AssertionResult const &result = _assertionStats.assertionResult;

    bool printInfoMessages = true;

    // Drop out if result was successful and we're not printing those
    if ( !m_config->includeSuccessfulResults() && result.isOk() )
      {
        if ( result.getResultType() != ResultWas::Warning )
          return false;
        printInfoMessages = false;
      }

    AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
    printer.print();

    stream << std::endl;
    return true;
  }

  void CompactReporter::sectionEnded(SectionStats const &_sectionStats)
  {
    if (m_config->showDurations() == ShowDurations::Always)
      {
        stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
      }
  }

                                                                   void CompactReporter::testRunEnded( TestRunStats const &_testRunStats )
  {
    printTotals( stream, _testRunStats.totals );
    stream << '\n' << std::endl;
            StreamingReporterBase::testRunEnded( _testRunStats );
  }

  CompactReporter::~CompactReporter() {}

  CATCH_REGISTER_REPORTER( "compact", CompactReporter )

} // end namespace Catch
// end catch_reporter_compact.cpp
// start catch_reporter_console.cpp

#include <cfloat>
#include <cstdio>

#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
// Note that 4062 (not all labels are handled
// and default is missing) is enabled
#endif

namespace Catch
{

  namespace
  {

// Formatter impl for ConsoleReporter
    class ConsoleAssertionPrinter
    {
      public:
      ConsoleAssertionPrinter &operator= (ConsoleAssertionPrinter const &) = delete;
      ConsoleAssertionPrinter(ConsoleAssertionPrinter const &) = delete;
      ConsoleAssertionPrinter(std::ostream &_stream, AssertionStats const &_stats, bool _printInfoMessages)
      : stream(_stream),
      stats(_stats),
      result(_stats.assertionResult),
      colour(Colour::None),
      message(result.getMessage()),
      messages(_stats.infoMessages),
      printInfoMessages(_printInfoMessages)
  {
    switch (result.getResultType())
      {
        case ResultWas::Ok:
          colour = Colour::Success;
          passOrFail = "PASSED";
          //if( result.hasMessage() )
          if (_stats.infoMessages.size() == 1)
            messageLabel = "with message";
          if (_stats.infoMessages.size() > 1)
            messageLabel = "with messages";
          break;
        case ResultWas::ExpressionFailed:
          if (result.isOk())
            {
              colour = Colour::Success;
              passOrFail = "FAILED - but was ok";
            }
          else
            {
              colour = Colour::Error;
              passOrFail = "FAILED";
            }
          if (_stats.infoMessages.size() == 1)
            messageLabel = "with message";
          if (_stats.infoMessages.size() > 1)
            messageLabel = "with messages";
          break;
        case ResultWas::ThrewException:
          colour = Colour::Error;
          passOrFail = "FAILED";
          messageLabel = "due to unexpected exception with ";
          if (_stats.infoMessages.size() == 1)
            messageLabel += "message";
          if (_stats.infoMessages.size() > 1)
            messageLabel += "messages";
          break;
        case ResultWas::FatalErrorCondition:
          colour = Colour::Error;
          passOrFail = "FAILED";
          messageLabel = "due to a fatal error condition";
          break;
        case ResultWas::DidntThrowException:
          colour = Colour::Error;
          passOrFail = "FAILED";
          messageLabel = "because no exception was thrown where one was expected";
          break;
        case ResultWas::Info:
          messageLabel = "info";
          break;
        case ResultWas::Warning:
          messageLabel = "warning";
          break;
        case ResultWas::ExplicitFailure:
          passOrFail = "FAILED";
          colour = Colour::Error;
          if (_stats.infoMessages.size() == 1)
            messageLabel = "explicitly with message";
          if (_stats.infoMessages.size() > 1)
            messageLabel = "explicitly with messages";
          break;
        // These cases are here to prevent compiler warnings
        case ResultWas::Unknown:
        case ResultWas::FailureBit:
        case ResultWas::Exception:
          passOrFail = "** internal error **";
          colour = Colour::Error;
          break;
      }
  }

  void print() const
  {
    printSourceInfo();
    if (stats.totals.assertions.total() > 0)
      {
        if (result.isOk())
          stream << '\n';
        printResultType();
        printOriginalExpression();
        printReconstructedExpression();
      }
    else
      {
        stream << '\n';
      }
    printMessage();
  }

  private:
  void printResultType() const
  {
    if (!passOrFail.empty())
      {
        Colour colourGuard(colour);
        stream << passOrFail << ":\n";
      }
  }
  void printOriginalExpression() const
  {
    if (result.hasExpression())
      {
        Colour colourGuard(Colour::OriginalExpression);
        stream << "  ";
        stream << result.getExpressionInMacro();
        stream << '\n';
      }
  }
  void printReconstructedExpression() const
  {
    if (result.hasExpandedExpression())
      {
        stream << "with expansion:\n";
        Colour colourGuard(Colour::ReconstructedExpression);
        stream << Column(result.getExpandedExpression()).indent(2) << '\n';
      }
  }
  void printMessage() const
  {
    if (!messageLabel.empty())
      stream << messageLabel << ':' << '\n';
                            for (auto const &msg : messages)
      {
        // If this assertion is a warning ignore any INFO messages
        if (printInfoMessages || msg.type != ResultWas::Info)
          stream << Column(msg.message).indent(2) << '\n';
      }
  }
  void printSourceInfo() const
  {
    Colour colourGuard(Colour::FileName);
    stream << result.getSourceInfo() << ": ";
  }

          std::ostream &stream;
          AssertionStats const &stats;
          AssertionResult const &result;
          Colour::Code colour;
          std::string passOrFail;
          std::string messageLabel;
          std::string message;
          std::vector<MessageInfo> messages;
          bool printInfoMessages;
                     };

  std::size_t makeRatio(std::size_t number, std::size_t total)
  {
    std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;
    return (ratio == 0 && number > 0) ? 1 : ratio;
  }

  std::size_t &findMax(std::size_t &i, std::size_t &j, std::size_t &k)
  {
    if (i > j && i > k)
      return i;
    else if (j > k)
      return j;
    else
      return k;
  }

  struct ColumnInfo
  {
    enum Justification { Left, Right };
    std::string name;
    int width;
    Justification justification;
  };
  struct ColumnBreak {};
  struct RowBreak {};

  class Duration
  {
    enum class Unit
    {
      Auto,
      Nanoseconds,
      Microseconds,
      Milliseconds,
      Seconds,
      Minutes
    };
    static const uint64_t s_nanosecondsInAMicrosecond = 1000;
    static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;
    static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
    static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;

    uint64_t m_inNanoseconds;
    Unit m_units;

    public:
    explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto)
    : m_inNanoseconds(inNanoseconds),
    m_units(units)
  {
    if (m_units == Unit::Auto)
      {
        if (m_inNanoseconds < s_nanosecondsInAMicrosecond)
              m_units = Unit::Nanoseconds;
        else if (m_inNanoseconds < s_nanosecondsInAMillisecond)
                   m_units = Unit::Microseconds;
        else if (m_inNanoseconds < s_nanosecondsInASecond)
                   m_units = Unit::Milliseconds;
        else if (m_inNanoseconds < s_nanosecondsInAMinute)
                   m_units = Unit::Seconds;
        else
          m_units = Unit::Minutes;
      }

  }

  auto value() const -> double
  {
    switch (m_units)
      {
        case Unit::Microseconds:
          return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);
        case Unit::Milliseconds:
          return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);
        case Unit::Seconds:
          return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);
        case Unit::Minutes:
          return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
        default:
          return static_cast<double>(m_inNanoseconds);
      }
  }
  auto unitsAsString() const -> std::string
  {
    switch (m_units)
      {
        case Unit::Nanoseconds:
          return "ns";
        case Unit::Microseconds:
          return "µs";
        case Unit::Milliseconds:
          return "ms";
        case Unit::Seconds:
          return "s";
        case Unit::Minutes:
          return "m";
        default:
          return "** internal error **";
      }

  }
  friend auto operator << (std::ostream &os, Duration const &duration) -> std::ostream &
  {
    return os << duration.value() << " " << duration.unitsAsString();
  }
                                       };
                                } // end anon namespace

  class TablePrinter
  {
    std::ostream &m_os;
    std::vector<ColumnInfo> m_columnInfos;
    std::ostringstream m_oss;
    int m_currentColumn = -1;
    bool m_isOpen = false;

    public:
    TablePrinter( std::ostream &os, std::vector<ColumnInfo> columnInfos )
    :   m_os( os ),
  m_columnInfos( std::move( columnInfos ) ) {}

  auto columnInfos() const -> std::vector<ColumnInfo> const &
  {
    return m_columnInfos;
  }

  void open()
  {
    if (!m_isOpen)
      {
        m_isOpen = true;
        *this << RowBreak();
        for (auto const &info : m_columnInfos)
          *this << info.name << ColumnBreak();
               *this << RowBreak();
               m_os << Catch::getLineOfChars<'-'>() << "\n";
      }
  }
         void close()
  {
    if (m_isOpen)
      {
        *this << RowBreak();
        m_os << std::endl;
        m_isOpen = false;
      }
  }

  template<typename T>
  friend TablePrinter &operator << (TablePrinter &tp, T const &value)
  {
    tp.m_oss << value;
    return tp;
  }

  friend TablePrinter &operator << (TablePrinter &tp, ColumnBreak)
  {
    auto colStr = tp.m_oss.str();
    // This takes account of utf8 encodings
    auto strSize = Catch::StringRef(colStr).numberOfCharacters();
    tp.m_oss.str("");
    tp.open();
    if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1))
      {
        tp.m_currentColumn = -1;
        tp.m_os << "\n";
      }
    tp.m_currentColumn++;

    auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
    auto padding = (strSize + 2 < static_cast<std::size_t>(colInfo.width))
                    ? std::string(colInfo.width - (strSize + 2), ' ')
                    : std::string();
    if (colInfo.justification == ColumnInfo::Left)
      tp.m_os << colStr << padding << " ";
                       else
                         tp.m_os << padding << colStr << " ";
                                           return tp;
  }

                                         friend TablePrinter &operator << (TablePrinter &tp, RowBreak)
  {
    if (tp.m_currentColumn > 0)
      {
        tp.m_os << "\n";
        tp.m_currentColumn = -1;
      }
    return tp;
  }
          };

  ConsoleReporter::ConsoleReporter(ReporterConfig const &config)
    : StreamingReporterBase(config),
      m_tablePrinter(new TablePrinter(config.stream(),
  {
    { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left },
    { "iters", 8, ColumnInfo::Right },
    { "elapsed ns", 14, ColumnInfo::Right },
    { "average", 14, ColumnInfo::Right }
  })) {}
  ConsoleReporter::~ConsoleReporter() = default;

  std::string ConsoleReporter::getDescription()
  {
    return "Reports test results as plain lines of text";
  }

  void ConsoleReporter::noMatchingTestCases(std::string const &spec)
  {
    stream << "No test cases matched '" << spec << '\'' << std::endl;
  }

  void ConsoleReporter::assertionStarting(AssertionInfo const &) {}

  bool ConsoleReporter::assertionEnded(AssertionStats const &_assertionStats)
  {
    AssertionResult const &result = _assertionStats.assertionResult;

    bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();

    // Drop out if result was successful but we're not printing them.
    if (!includeResults && result.getResultType() != ResultWas::Warning)
      return false;

    lazyPrint();

    ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);
    printer.print();
    stream << std::endl;
    return true;
  }

  void ConsoleReporter::sectionStarting(SectionInfo const &_sectionInfo)
  {
    m_headerPrinted = false;
    StreamingReporterBase::sectionStarting(_sectionInfo);
  }
  void ConsoleReporter::sectionEnded(SectionStats const &_sectionStats)
  {
    m_tablePrinter->close();
    if (_sectionStats.missingAssertions)
      {
        lazyPrint();
        Colour colour(Colour::ResultError);
        if (m_sectionStack.size() > 1)
          stream << "\nNo assertions in section";
        else
          stream << "\nNo assertions in test case";
        stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
      }
                                                      if (m_config->showDurations() == ShowDurations::Always)
      {
        stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
      }
                                                                               if (m_headerPrinted)
      {
        m_headerPrinted = false;
      }
    StreamingReporterBase::sectionEnded(_sectionStats);
  }

  void ConsoleReporter::benchmarkStarting(BenchmarkInfo const &info)
  {
    lazyPrintWithoutClosingBenchmarkTable();

    auto nameCol = Column( info.name ).width( static_cast<std::size_t>( m_tablePrinter->columnInfos()[0].width - 2 ) );

    bool firstLine = true;
    for (auto line : nameCol)
      {
        if (!firstLine)
          (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();
                                            else
                                              firstLine = false;

                                            (*m_tablePrinter) << line << ColumnBreak();
      }
  }
                                      void ConsoleReporter::benchmarkEnded(BenchmarkStats const &stats)
  {
    Duration average(stats.elapsedTimeInNanoseconds / stats.iterations);
    (*m_tablePrinter)
    << stats.iterations << ColumnBreak()
                         << stats.elapsedTimeInNanoseconds << ColumnBreak()
                                                            << average << ColumnBreak();
  }

                                                           void ConsoleReporter::testCaseEnded(TestCaseStats const &_testCaseStats)
  {
    m_tablePrinter->close();
    StreamingReporterBase::testCaseEnded(_testCaseStats);
    m_headerPrinted = false;
  }
  void ConsoleReporter::testGroupEnded(TestGroupStats const &_testGroupStats)
  {
    if (currentGroupInfo.used)
      {
        printSummaryDivider();
        stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
                                         printTotals(_testGroupStats.totals);
                                         stream << '\n' << std::endl;
      }
                                             StreamingReporterBase::testGroupEnded(_testGroupStats);
  }
                                   void ConsoleReporter::testRunEnded(TestRunStats const &_testRunStats)
  {
    printTotalsDivider(_testRunStats.totals);
    printTotals(_testRunStats.totals);
    stream << std::endl;
    StreamingReporterBase::testRunEnded(_testRunStats);
  }

  void ConsoleReporter::lazyPrint()
  {

    m_tablePrinter->close();
    lazyPrintWithoutClosingBenchmarkTable();
  }

  void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable()
  {

    if (!currentTestRunInfo.used)
      lazyPrintRunInfo();
    if (!currentGroupInfo.used)
      lazyPrintGroupInfo();

    if (!m_headerPrinted)
      {
        printTestCaseAndSectionHeader();
        m_headerPrinted = true;
      }
  }
  void ConsoleReporter::lazyPrintRunInfo()
  {
    stream << '\n' << getLineOfChars<'~'>() << '\n';
                    Colour colour(Colour::SecondaryText);
                    stream << currentTestRunInfo->name
                            << " is a Catch v" << libraryVersion() << " host application.\n"
                                                                    << "Run with -? for options\n\n";

                                                                    if (m_config->rngSeed() != 0)
                                                                      stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";

                                                                            currentTestRunInfo.used = true;
  }
                                                                          void ConsoleReporter::lazyPrintGroupInfo()
  {
    if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1)
      {
        printClosedHeader("Group: " + currentGroupInfo->name);
        currentGroupInfo.used = true;
      }
  }
  void ConsoleReporter::printTestCaseAndSectionHeader()
  {
    assert(!m_sectionStack.empty());
    printOpenHeader(currentTestCaseInfo->name);

    if (m_sectionStack.size() > 1)
      {
        Colour colourGuard(Colour::Headers);

        auto
        it = m_sectionStack.begin() + 1, // Skip first section (test case)
        itEnd = m_sectionStack.end();
        for (; it != itEnd; ++it)
          printHeaderString(it->name, 2);
      }

    SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;

    if (!lineInfo.empty())
      {
        stream << getLineOfChars<'-'>() << '\n';
                Colour colourGuard(Colour::FileName);
                stream << lineInfo << '\n';
      }
                    stream << getLineOfChars<'.'>() << '\n' << std::endl;
  }

                                                   void ConsoleReporter::printClosedHeader(std::string const &_name)
  {
    printOpenHeader(_name);
    stream << getLineOfChars<'.'>() << '\n';
  }
          void ConsoleReporter::printOpenHeader(std::string const &_name)
  {
    stream << getLineOfChars<'-'>() << '\n';
    {
      Colour colourGuard(Colour::Headers);
      printHeaderString(_name);
    }
  }

// if string has a : in first line will set indent to follow it on
// subsequent lines
  void ConsoleReporter::printHeaderString(std::string const &_string, std::size_t indent)
  {
    std::size_t i = _string.find(": ");
    if (i != std::string::npos)
      i += 2;
    else
      i = 0;
    stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n';
  }

          struct SummaryColumn
          {

            SummaryColumn( std::string _label, Colour::Code _colour )
            :   label( std::move( _label ) ),
  colour( _colour ) {}
  SummaryColumn addRow( std::size_t count )
  {
    ReusableStringStream rss;
    rss << count;
    std::string row = rss.str();
    for (auto &oldRow : rows)
      {
        while (oldRow.size() < row.size())
                 oldRow = ' ' + oldRow;
        while (oldRow.size() > row.size())
          row = ' ' + row;
      }
    rows.push_back(row);
    return *this;
  }

  std::string label;
  Colour::Code colour;
  std::vector<std::string> rows;

             };

  void ConsoleReporter::printTotals( Totals const &totals )
  {
    if (totals.testCases.total() == 0)
      {
        stream << Colour(Colour::Warning) << "No tests ran\n";
      }
            else if (totals.assertions.total() > 0 && totals.testCases.allPassed())
      {
        stream << Colour(Colour::ResultSuccess) << "All tests passed";
                stream << " ("
                        << pluralise(totals.assertions.passed, "assertion") << " in "
                                                                             << pluralise(totals.testCases.passed, "test case") << ')'
                                                                                 << '\n';
      }
                                                                             else
      {

        std::vector<SummaryColumn> columns;
        columns.push_back(SummaryColumn("", Colour::None)
                          .addRow(totals.testCases.total())
                          .addRow(totals.assertions.total()));
        columns.push_back(SummaryColumn("passed", Colour::Success)
                          .addRow(totals.testCases.passed)
                          .addRow(totals.assertions.passed));
        columns.push_back(SummaryColumn("failed", Colour::ResultError)
                          .addRow(totals.testCases.failed)
                          .addRow(totals.assertions.failed));
        columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
                          .addRow(totals.testCases.failedButOk)
                          .addRow(totals.assertions.failedButOk));

        printSummaryRow("test cases", columns, 0);
        printSummaryRow("assertions", columns, 1);
      }
  }
  void ConsoleReporter::printSummaryRow(std::string const &label, std::vector<SummaryColumn> const &cols, std::size_t row)
  {
    for (auto col : cols)
      {
        std::string value = col.rows[row];
        if (col.label.empty())
          {
            stream << label << ": ";
                    if (value != "0")
                      stream << value;
                    else
                      stream << Colour(Colour::Warning) << "- none -";
          }
                        else if (value != "0")
          {
            stream << Colour(Colour::LightGrey) << " | ";
                    stream << Colour(col.colour)
                            << value << ' ' << col.label;
          }
      }
                     stream << '\n';
  }

                   void ConsoleReporter::printTotalsDivider(Totals const &totals)
  {
    if (totals.testCases.total() > 0)
      {
        std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
        std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());
        std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());
        while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)
                 findMax(failedRatio, failedButOkRatio, passedRatio)++;
        while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)
          findMax(failedRatio, failedButOkRatio, passedRatio)--;

        stream << Colour(Colour::Error) << std::string(failedRatio, '=');
                stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');
                        if (totals.testCases.allPassed())
                          stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');
                                else
                                  stream << Colour(Colour::Success) << std::string(passedRatio, '=');
      }
                                    else
      {
        stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');
      }
            stream << '\n';
  }
          void ConsoleReporter::printSummaryDivider()
  {
    stream << getLineOfChars<'-'>() << '\n';
  }

          CATCH_REGISTER_REPORTER("console", ConsoleReporter)

} // end namespace Catch

#if defined(_MSC_VER)
#pragma warning(pop)
#endif
// end catch_reporter_console.cpp
// start catch_reporter_junit.cpp

#include <cassert>
#include <sstream>
#include <ctime>
#include <algorithm>

namespace Catch
{

  namespace
  {
    std::string getCurrentTimestamp()
  {
    // Beware, this is not reentrant because of backward compatibility issues
    // Also, UTC only, again because of backward compatibility (%z is C++11)
    time_t rawtime;
    std::time(&rawtime);
    auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");

#ifdef _MSC_VER
    std::tm timeInfo = {};
    gmtime_s(&timeInfo, &rawtime);
#else
    std::tm *timeInfo;
    timeInfo = std::gmtime(&rawtime);
#endif

    char timeStamp[timeStampSize];
    const char *const fmt = "%Y-%m-%dT%H:%M:%SZ";

#ifdef _MSC_VER
    std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
#else
    std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
#endif
    return std::string(timeStamp);
  }

  std::string fileNameTag(const std::vector<std::string> &tags)
  {
    auto it = std::find_if(begin(tags),
                           end(tags),
                           [] (std::string const& tag)
    {
      return tag.front() == '#';
    });
    if (it != tags.end())
      return it->substr(1);
    return std::string();
  }
                         } // anonymous namespace

  JunitReporter::JunitReporter( ReporterConfig const &_config )
    :   CumulativeReporterBase( _config ),
        xml( _config.stream() )
  {
    m_reporterPrefs.shouldRedirectStdOut = true;
  }

  JunitReporter::~JunitReporter() {}

  std::string JunitReporter::getDescription()
  {
    return "Reports test results in an XML format that looks like Ant's junitreport target";
  }

  void JunitReporter::noMatchingTestCases( std::string const & /*spec*/ ) {}

  void JunitReporter::testRunStarting( TestRunInfo const &runInfo )
  {
    CumulativeReporterBase::testRunStarting( runInfo );
    xml.startElement( "testsuites" );
  }

  void JunitReporter::testGroupStarting( GroupInfo const &groupInfo )
  {
    suiteTimer.start();
    stdOutForSuite.clear();
    stdErrForSuite.clear();
    unexpectedExceptions = 0;
    CumulativeReporterBase::testGroupStarting( groupInfo );
  }

  void JunitReporter::testCaseStarting( TestCaseInfo const &testCaseInfo )
  {
    m_okToFail = testCaseInfo.okToFail();
  }

  bool JunitReporter::assertionEnded( AssertionStats const &assertionStats )
  {
    if ( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
      unexpectedExceptions++;
    return CumulativeReporterBase::assertionEnded( assertionStats );
  }

  void JunitReporter::testCaseEnded( TestCaseStats const &testCaseStats )
  {
    stdOutForSuite += testCaseStats.stdOut;
    stdErrForSuite += testCaseStats.stdErr;
    CumulativeReporterBase::testCaseEnded( testCaseStats );
  }

  void JunitReporter::testGroupEnded( TestGroupStats const &testGroupStats )
  {
    double suiteTime = suiteTimer.getElapsedSeconds();
    CumulativeReporterBase::testGroupEnded( testGroupStats );
    writeGroup( *m_testGroups.back(), suiteTime );
  }

  void JunitReporter::testRunEndedCumulative()
  {
    xml.endElement();
  }

  void JunitReporter::writeGroup( TestGroupNode const &groupNode, double suiteTime )
  {
    XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
    TestGroupStats const &stats = groupNode.value;
    xml.writeAttribute( "name", stats.groupInfo.name );
    xml.writeAttribute( "errors", unexpectedExceptions );
    xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
    xml.writeAttribute( "tests", stats.totals.assertions.total() );
    xml.writeAttribute( "hostname", "tbd" ); // !TBD
    if ( m_config->showDurations() == ShowDurations::Never )
      xml.writeAttribute( "time", "" );
    else
      xml.writeAttribute( "time", suiteTime );
    xml.writeAttribute( "timestamp", getCurrentTimestamp() );

    // Write test cases
    for ( auto const &child : groupNode.children )
      writeTestCase( *child );

    xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), false );
    xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), false );
  }

  void JunitReporter::writeTestCase( TestCaseNode const &testCaseNode )
  {
    TestCaseStats const &stats = testCaseNode.value;

    // All test cases have exactly one section - which represents the
    // test case itself. That section may have 0-n nested sections
    assert( testCaseNode.children.size() == 1 );
    SectionNode const &rootSection = *testCaseNode.children.front();

    std::string className = stats.testInfo.className;

    if ( className.empty() )
      {
        className = fileNameTag(stats.testInfo.tags);
        if ( className.empty() )
          className = "global";
      }

    if ( !m_config->name().empty() )
      className = m_config->name() + "." + className;

    writeSection( className, "", rootSection );
  }

  void JunitReporter::writeSection(  std::string const &className,
                                     std::string const &rootName,
                                     SectionNode const &sectionNode )
  {
    std::string name = trim( sectionNode.stats.sectionInfo.name );
    if ( !rootName.empty() )
      name = rootName + '/' + name;

    if ( !sectionNode.assertions.empty() ||
         !sectionNode.stdOut.empty() ||
         !sectionNode.stdErr.empty() )
      {
        XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
        if ( className.empty() )
          {
            xml.writeAttribute( "classname", name );
            xml.writeAttribute( "name", "root" );
          }
        else
          {
            xml.writeAttribute( "classname", className );
            xml.writeAttribute( "name", name );
          }
        xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );

        writeAssertions( sectionNode );

        if ( !sectionNode.stdOut.empty() )
          xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
        if ( !sectionNode.stdErr.empty() )
          xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
      }
    for ( auto const &childNode : sectionNode.childSections )
      if ( className.empty() )
        writeSection( name, "", *childNode );
      else
        writeSection( className, name, *childNode );
  }

  void JunitReporter::writeAssertions( SectionNode const &sectionNode )
  {
    for ( auto const &assertion : sectionNode.assertions )
      writeAssertion( assertion );
  }

  void JunitReporter::writeAssertion( AssertionStats const &stats )
  {
    AssertionResult const &result = stats.assertionResult;
    if ( !result.isOk() )
      {
        std::string elementName;
        switch ( result.getResultType() )
          {
            case ResultWas::ThrewException:
            case ResultWas::FatalErrorCondition:
              elementName = "error";
              break;
            case ResultWas::ExplicitFailure:
              elementName = "failure";
              break;
            case ResultWas::ExpressionFailed:
              elementName = "failure";
              break;
            case ResultWas::DidntThrowException:
              elementName = "failure";
              break;

            // We should never see these here:
            case ResultWas::Info:
            case ResultWas::Warning:
            case ResultWas::Ok:
            case ResultWas::Unknown:
            case ResultWas::FailureBit:
            case ResultWas::Exception:
              elementName = "internalError";
              break;
          }

        XmlWriter::ScopedElement e = xml.scopedElement( elementName );

        xml.writeAttribute( "message", result.getExpandedExpression() );
        xml.writeAttribute( "type", result.getTestMacroName() );

        ReusableStringStream rss;
        if ( !result.getMessage().empty() )
          rss << result.getMessage() << '\n';
             for ( auto const &msg : stats.infoMessages )
               if ( msg.type == ResultWas::Info )
                 rss << msg.message << '\n';

                  rss << "at " << result.getSourceInfo();
                       xml.writeText( rss.str(), false );
      }
  }

            CATCH_REGISTER_REPORTER( "junit", JunitReporter )

} // end namespace Catch
// end catch_reporter_junit.cpp
// start catch_reporter_listening.cpp

#include <cassert>

          namespace Catch
{

  void ListeningReporter::addListener( IStreamingReporterPtr&& listener )
  {
    m_listeners.push_back( std::move( listener ) );
  }

  void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter)
  {
    assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
    m_reporter = std::move( reporter );
  }

  ReporterPreferences ListeningReporter::getPreferences() const
  {
    return m_reporter->getPreferences();
  }

  std::set<Verbosity> ListeningReporter::getSupportedVerbosities()
  {
    return std::set<Verbosity> { };
  }

  void ListeningReporter::noMatchingTestCases( std::string const &spec )
  {
    for ( auto const &listener : m_listeners )
      {
        listener->noMatchingTestCases( spec );
      }
    m_reporter->noMatchingTestCases( spec );
  }

  void ListeningReporter::benchmarkStarting( BenchmarkInfo const &benchmarkInfo )
  {
    for ( auto const &listener : m_listeners )
      {
        listener->benchmarkStarting( benchmarkInfo );
      }
    m_reporter->benchmarkStarting( benchmarkInfo );
  }
  void ListeningReporter::benchmarkEnded( BenchmarkStats const &benchmarkStats )
  {
    for ( auto const &listener : m_listeners )
      {
        listener->benchmarkEnded( benchmarkStats );
      }
    m_reporter->benchmarkEnded( benchmarkStats );
  }

  void ListeningReporter::testRunStarting( TestRunInfo const &testRunInfo )
  {
    for ( auto const &listener : m_listeners )
      {
        listener->testRunStarting( testRunInfo );
      }
    m_reporter->testRunStarting( testRunInfo );
  }

  void ListeningReporter::testGroupStarting( GroupInfo const &groupInfo )
  {
    for ( auto const &listener : m_listeners )
      {
        listener->testGroupStarting( groupInfo );
      }
    m_reporter->testGroupStarting( groupInfo );
  }

  void ListeningReporter::testCaseStarting( TestCaseInfo const &testInfo )
  {
    for ( auto const &listener : m_listeners )
      {
        listener->testCaseStarting( testInfo );
      }
    m_reporter->testCaseStarting( testInfo );
  }

  void ListeningReporter::sectionStarting( SectionInfo const &sectionInfo )
  {
    for ( auto const &listener : m_listeners )
      {
        listener->sectionStarting( sectionInfo );
      }
    m_reporter->sectionStarting( sectionInfo );
  }

  void ListeningReporter::assertionStarting( AssertionInfo const &assertionInfo )
  {
    for ( auto const &listener : m_listeners )
      {
        listener->assertionStarting( assertionInfo );
      }
    m_reporter->assertionStarting( assertionInfo );
  }

  // The return value indicates if the messages buffer should be cleared:
  bool ListeningReporter::assertionEnded( AssertionStats const &assertionStats )
  {
    for ( auto const &listener : m_listeners )
      {
        static_cast<void>( listener->assertionEnded( assertionStats ) );
      }
    return m_reporter->assertionEnded( assertionStats );
  }

  void ListeningReporter::sectionEnded( SectionStats const &sectionStats )
  {
    for ( auto const &listener : m_listeners )
      {
        listener->sectionEnded( sectionStats );
      }
    m_reporter->sectionEnded( sectionStats );
  }

  void ListeningReporter::testCaseEnded( TestCaseStats const &testCaseStats )
  {
    for ( auto const &listener : m_listeners )
      {
        listener->testCaseEnded( testCaseStats );
      }
    m_reporter->testCaseEnded( testCaseStats );
  }

  void ListeningReporter::testGroupEnded( TestGroupStats const &testGroupStats )
  {
    for ( auto const &listener : m_listeners )
      {
        listener->testGroupEnded( testGroupStats );
      }
    m_reporter->testGroupEnded( testGroupStats );
  }

  void ListeningReporter::testRunEnded( TestRunStats const &testRunStats )
  {
    for ( auto const &listener : m_listeners )
      {
        listener->testRunEnded( testRunStats );
      }
    m_reporter->testRunEnded( testRunStats );
  }

  void ListeningReporter::skipTest( TestCaseInfo const &testInfo )
  {
    for ( auto const &listener : m_listeners )
      {
        listener->skipTest( testInfo );
      }
    m_reporter->skipTest( testInfo );
  }

  bool ListeningReporter::isMulti() const
  {
    return true;
  }

} // end namespace Catch
// end catch_reporter_listening.cpp
// start catch_reporter_xml.cpp

#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch
// Note that 4062 (not all labels are handled
// and default is missing) is enabled
#endif

namespace Catch
{
  XmlReporter::XmlReporter( ReporterConfig const &_config )
    :   StreamingReporterBase( _config ),
        m_xml(_config.stream())
  {
    m_reporterPrefs.shouldRedirectStdOut = true;
  }

  XmlReporter::~XmlReporter() = default;

  std::string XmlReporter::getDescription()
  {
    return "Reports test results as an XML document";
  }

  std::string XmlReporter::getStylesheetRef() const
  {
    return std::string();
  }

  void XmlReporter::writeSourceInfo( SourceLineInfo const &sourceInfo )
  {
    m_xml
    .writeAttribute( "filename", sourceInfo.file )
    .writeAttribute( "line", sourceInfo.line );
  }

  void XmlReporter::noMatchingTestCases( std::string const &s )
  {
    StreamingReporterBase::noMatchingTestCases( s );
  }

  void XmlReporter::testRunStarting( TestRunInfo const &testInfo )
  {
    StreamingReporterBase::testRunStarting( testInfo );
    std::string stylesheetRef = getStylesheetRef();
    if ( !stylesheetRef.empty() )
      m_xml.writeStylesheetRef( stylesheetRef );
    m_xml.startElement( "Catch" );
    if ( !m_config->name().empty() )
      m_xml.writeAttribute( "name", m_config->name() );
  }

  void XmlReporter::testGroupStarting( GroupInfo const &groupInfo )
  {
    StreamingReporterBase::testGroupStarting( groupInfo );
    m_xml.startElement( "Group" )
    .writeAttribute( "name", groupInfo.name );
  }

  void XmlReporter::testCaseStarting( TestCaseInfo const &testInfo )
  {
    StreamingReporterBase::testCaseStarting(testInfo);
    m_xml.startElement( "TestCase" )
    .writeAttribute( "name", trim( testInfo.name ) )
    .writeAttribute( "description", testInfo.description )
    .writeAttribute( "tags", testInfo.tagsAsString() );

    writeSourceInfo( testInfo.lineInfo );

    if ( m_config->showDurations() == ShowDurations::Always )
      m_testCaseTimer.start();
    m_xml.ensureTagClosed();
  }

  void XmlReporter::sectionStarting( SectionInfo const &sectionInfo )
  {
    StreamingReporterBase::sectionStarting( sectionInfo );
    if ( m_sectionDepth++ > 0 )
      {
        m_xml.startElement( "Section" )
        .writeAttribute( "name", trim( sectionInfo.name ) )
        .writeAttribute( "description", sectionInfo.description );
        writeSourceInfo( sectionInfo.lineInfo );
        m_xml.ensureTagClosed();
      }
  }

  void XmlReporter::assertionStarting( AssertionInfo const &) { }

  bool XmlReporter::assertionEnded( AssertionStats const &assertionStats )
  {

    AssertionResult const &result = assertionStats.assertionResult;

    bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();

    if ( includeResults || result.getResultType() == ResultWas::Warning )
      {
        // Print any info messages in <Info> tags.
        for ( auto const &msg : assertionStats.infoMessages )
          {
            if ( msg.type == ResultWas::Info && includeResults )
              {
                m_xml.scopedElement( "Info" )
                .writeText( msg.message );
              }
            else if ( msg.type == ResultWas::Warning )
              {
                m_xml.scopedElement( "Warning" )
                .writeText( msg.message );
              }
          }
      }

    // Drop out if result was successful but we're not printing them.
    if ( !includeResults && result.getResultType() != ResultWas::Warning )
      return true;

    // Print the expression if there is one.
    if ( result.hasExpression() )
      {
        m_xml.startElement( "Expression" )
        .writeAttribute( "success", result.succeeded() )
        .writeAttribute( "type", result.getTestMacroName() );

        writeSourceInfo( result.getSourceInfo() );

        m_xml.scopedElement( "Original" )
        .writeText( result.getExpression() );
        m_xml.scopedElement( "Expanded" )
        .writeText( result.getExpandedExpression() );
      }

    // And... Print a result applicable to each result type.
    switch ( result.getResultType() )
      {
        case ResultWas::ThrewException:
          m_xml.startElement( "Exception" );
          writeSourceInfo( result.getSourceInfo() );
          m_xml.writeText( result.getMessage() );
          m_xml.endElement();
          break;
        case ResultWas::FatalErrorCondition:
          m_xml.startElement( "FatalErrorCondition" );
          writeSourceInfo( result.getSourceInfo() );
          m_xml.writeText( result.getMessage() );
          m_xml.endElement();
          break;
        case ResultWas::Info:
          m_xml.scopedElement( "Info" )
          .writeText( result.getMessage() );
          break;
        case ResultWas::Warning:
          // Warning will already have been written
          break;
        case ResultWas::ExplicitFailure:
          m_xml.startElement( "Failure" );
          writeSourceInfo( result.getSourceInfo() );
          m_xml.writeText( result.getMessage() );
          m_xml.endElement();
          break;
        default:
          break;
      }

    if ( result.hasExpression() )
      m_xml.endElement();

    return true;
  }

  void XmlReporter::sectionEnded( SectionStats const &sectionStats )
  {
    StreamingReporterBase::sectionEnded( sectionStats );
    if ( --m_sectionDepth > 0 )
      {
        XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
        e.writeAttribute( "successes", sectionStats.assertions.passed );
        e.writeAttribute( "failures", sectionStats.assertions.failed );
        e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );

        if ( m_config->showDurations() == ShowDurations::Always )
          e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );

        m_xml.endElement();
      }
  }

  void XmlReporter::testCaseEnded( TestCaseStats const &testCaseStats )
  {
    StreamingReporterBase::testCaseEnded( testCaseStats );
    XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
    e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );

    if ( m_config->showDurations() == ShowDurations::Always )
      e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );

    if ( !testCaseStats.stdOut.empty() )
      m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false );
    if ( !testCaseStats.stdErr.empty() )
      m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false );

    m_xml.endElement();
  }

  void XmlReporter::testGroupEnded( TestGroupStats const &testGroupStats )
  {
    StreamingReporterBase::testGroupEnded( testGroupStats );
    // TODO: Check testGroupStats.aborting and act accordingly.
    m_xml.scopedElement( "OverallResults" )
    .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
    .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
    .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
    m_xml.endElement();
  }

  void XmlReporter::testRunEnded( TestRunStats const &testRunStats )
  {
    StreamingReporterBase::testRunEnded( testRunStats );
    m_xml.scopedElement( "OverallResults" )
    .writeAttribute( "successes", testRunStats.totals.assertions.passed )
    .writeAttribute( "failures", testRunStats.totals.assertions.failed )
    .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
    m_xml.endElement();
  }

  CATCH_REGISTER_REPORTER( "xml", XmlReporter )

} // end namespace Catch

#if defined(_MSC_VER)
#pragma warning(pop)
#endif
// end catch_reporter_xml.cpp

namespace Catch
{
  LeakDetector leakDetector;
}

#ifdef __clang__
#pragma clang diagnostic pop
#endif

// end catch_impl.hpp
#endif

#ifdef CATCH_CONFIG_MAIN
// start catch_default_main.hpp

#ifndef __OBJC__

#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
// Standard C/C++ Win32 Unicode wmain entry point
extern "C" int wmain (int argc, wchar_t *argv[], wchar_t *[])
{
#else
// Standard C/C++ main entry point
int main (int argc, char *argv[])
{
#endif

  return Catch::Session().run( argc, argv );
}

#else // __OBJC__

// Objective-C entry point
int main (int argc, char *const argv[])
{
#if !CATCH_ARC_ENABLED
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
#endif

  Catch::registerTestMethods();
  int result = Catch::Session().run( argc, (char **)argv );

#if !CATCH_ARC_ENABLED
  [pool drain];
#endif

  return result;
}

#endif // __OBJC__

// end catch_default_main.hpp
#endif

#if !defined(CATCH_CONFIG_IMPL_ONLY)

#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
#  undef CLARA_CONFIG_MAIN
#endif

#if !defined(CATCH_CONFIG_DISABLE)
//////
// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
#ifdef CATCH_CONFIG_PREFIX_ALL

#define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
#define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )

#define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", __VA_ARGS__ )
#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
#endif// CATCH_CONFIG_DISABLE_MATCHERS
#define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )

#define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
#define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )

#define CATCH_CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", __VA_ARGS__ )
#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
#endif // CATCH_CONFIG_DISABLE_MATCHERS
#define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )

#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )

#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
#endif // CATCH_CONFIG_DISABLE_MATCHERS

#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) )

#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
#define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )

#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()

// "BDD-style" convenience wrappers
#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
#define CATCH_GIVEN( desc )    CATCH_SECTION( std::string( "Given: ") + desc )
#define CATCH_WHEN( desc )     CATCH_SECTION( std::string( " When: ") + desc )
#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc )
#define CATCH_THEN( desc )     CATCH_SECTION( std::string( " Then: ") + desc )
#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc )

// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
#else

#define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__  )
#define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )

#define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ )
#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
#endif // CATCH_CONFIG_DISABLE_MATCHERS
#define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ )

#define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
#define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )

#define CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
#endif // CATCH_CONFIG_DISABLE_MATCHERS
#define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )

#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )

#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
#endif // CATCH_CONFIG_DISABLE_MATCHERS

#define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
#define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
#define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) )

#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
#define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()

#endif

#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )

// "BDD-style" convenience wrappers
#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )

#define GIVEN( desc )    SECTION( std::string("   Given: ") + desc )
#define WHEN( desc )     SECTION( std::string("    When: ") + desc )
#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc )
#define THEN( desc )     SECTION( std::string("    Then: ") + desc )
#define AND_THEN( desc ) SECTION( std::string("     And: ") + desc )

using Catch::Detail::Approx;

#else
//////
// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
#ifdef CATCH_CONFIG_PREFIX_ALL

#define CATCH_REQUIRE( ... )        (void)(0)
#define CATCH_REQUIRE_FALSE( ... )  (void)(0)

#define CATCH_REQUIRE_THROWS( ... ) (void)(0)
#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
#define CATCH_REQUIRE_THROWS_WITH( expr, matcher )     (void)(0)
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
#endif// CATCH_CONFIG_DISABLE_MATCHERS
#define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)

#define CATCH_CHECK( ... )         (void)(0)
#define CATCH_CHECK_FALSE( ... )   (void)(0)
#define CATCH_CHECKED_IF( ... )    if (__VA_ARGS__)
#define CATCH_CHECKED_ELSE( ... )  if (!(__VA_ARGS__))
#define CATCH_CHECK_NOFAIL( ... )  (void)(0)

#define CATCH_CHECK_THROWS( ... )  (void)(0)
#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
#define CATCH_CHECK_THROWS_WITH( expr, matcher )     (void)(0)
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
#endif // CATCH_CONFIG_DISABLE_MATCHERS
#define CATCH_CHECK_NOTHROW( ... ) (void)(0)

#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define CATCH_CHECK_THAT( arg, matcher )   (void)(0)

#define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
#endif // CATCH_CONFIG_DISABLE_MATCHERS

#define CATCH_INFO( msg )    (void)(0)
#define CATCH_WARN( msg )    (void)(0)
#define CATCH_CAPTURE( msg ) (void)(0)

#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
#define CATCH_METHOD_AS_TEST_CASE( method, ... )
#define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
#define CATCH_SECTION( ... )
#define CATCH_FAIL( ... ) (void)(0)
#define CATCH_FAIL_CHECK( ... ) (void)(0)
#define CATCH_SUCCEED( ... ) (void)(0)

#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))

// "BDD-style" convenience wrappers
#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
#define CATCH_GIVEN( desc )
#define CATCH_WHEN( desc )
#define CATCH_AND_WHEN( desc )
#define CATCH_THEN( desc )
#define CATCH_AND_THEN( desc )

// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
#else

#define REQUIRE( ... )       (void)(0)
#define REQUIRE_FALSE( ... ) (void)(0)

#define REQUIRE_THROWS( ... ) (void)(0)
#define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)
#define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
#endif // CATCH_CONFIG_DISABLE_MATCHERS
#define REQUIRE_NOTHROW( ... ) (void)(0)

#define CHECK( ... ) (void)(0)
#define CHECK_FALSE( ... ) (void)(0)
#define CHECKED_IF( ... ) if (__VA_ARGS__)
#define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))
#define CHECK_NOFAIL( ... ) (void)(0)

#define CHECK_THROWS( ... )  (void)(0)
#define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)
#define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
#endif // CATCH_CONFIG_DISABLE_MATCHERS
#define CHECK_NOTHROW( ... ) (void)(0)

#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
#define CHECK_THAT( arg, matcher ) (void)(0)

#define REQUIRE_THAT( arg, matcher ) (void)(0)
#endif // CATCH_CONFIG_DISABLE_MATCHERS

#define INFO( msg ) (void)(0)
#define WARN( msg ) (void)(0)
#define CAPTURE( msg ) (void)(0)

#define TEST_CASE( ... )  INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
#define METHOD_AS_TEST_CASE( method, ... )
#define REGISTER_TEST_CASE( Function, ... ) (void)(0)
#define SECTION( ... )
#define FAIL( ... ) (void)(0)
#define FAIL_CHECK( ... ) (void)(0)
#define SUCCEED( ... ) (void)(0)
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))

#endif

#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )

// "BDD-style" convenience wrappers
#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) )
#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )

#define GIVEN( desc )
#define WHEN( desc )
#define AND_WHEN( desc )
#define THEN( desc )
#define AND_THEN( desc )

using Catch::Detail::Approx;

#endif

#endif // ! CATCH_CONFIG_IMPL_ONLY

// start catch_reenable_warnings.h


#ifdef __clang__
#    ifdef __ICC // icpc defines the __clang__ macro
#        pragma warning(pop)
#    else
#        pragma clang diagnostic pop
#    endif
#elif defined __GNUC__
#    pragma GCC diagnostic pop
#endif

// end catch_reenable_warnings.h
// end catch.hpp
#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED


